如何解决前后端分离时的跨域问题
遇到的问题
前端项目的本机端口号
后端项目的端口号
端口号不同导致的网络请求失败
问题产生原因
- 什么是跨域?
当一个请求url的协议、域名、端口三者之间任意一个与当前页面url不同即为跨域 - 出现跨域问题的原因
跨域问题是出于浏览器的同源策略限制。同源策略(Sameoriginpolicy)是一种约定,它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,则浏览器的正常功能可能都会受到影响。可以说Web是构建在同源策略基础之上的,浏览器只是针对同源策略的一种实现。同源策略会阻止一个域的javascript脚本和另外一个域的内容进行交互。所谓同源(即指在同一个域)就是两个页面具有相同的协议(protocol),主机(host)和端口号(port)。
解决思路
修改前端或者后端的配置,允许端口号等重定向为相同或者允许端口
解决办法
第一种:修改后端(以Vistual studio的ASP.NET Core Web API项目为例)
//Program.cs
using System;
namespace _01WebAPP
{
public class Program
{
public static void Main(string[] args)
{
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
// 添加CORS服务
builder.Services.AddCors(options =>
{
options.AddPolicy(name: "AllowSpecificOrigins",
builder =>
{
builder.WithOrigins("http://localhost:5173") // 允许来自Vue应用的请求,此处端口号为前端项目打开后的端口号
.AllowAnyHeader() // 允许任何头
.AllowAnyMethod(); // 允许任何方法
});
});
builder.Services.AddControllers();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
var app = builder.Build();
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI();
}
// 应用CORS策略
app.UseCors("AllowSpecificOrigins");
app.UseAuthorization();
app.MapControllers();
app.Run();
}
}
}
CORS服务
解释:跨源资源共享(CORS,或通俗地译为跨域资源共享)是一种基于 HTTP 头的机制,该机制通过允许服务器标示除了它自己以外的其他源(域、协议或端口),使得浏览器允许这些源访问加载自己的资源。跨源资源共享还通过一种机制来检查服务器是否会允许要发送的真实请求,该机制通过浏览器发起一个到服务器托管的跨源资源的“预检”请求。在预检中,浏览器发送的头中标示有 HTTP 方法和真实请求中会用到的头。
第二种:修改前端(以Vite+Vue项目为例)
//Vite.config.ts
import { fileURLToPath, URL } from 'node:url'
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import VueSetupExtend from 'vite-plugin-vue-setup-extend'
export default defineConfig({
plugins: [
vue(),
VueSetupExtend()
],
resolve: {
alias: {
'@': fileURLToPath(new URL('./src', import.meta.url))
}
},
server:{
proxy:{
'/api': {
target: 'http://localhost:5009', // 后端服务器的地址
changeOrigin: true, // 是否需要改变原始主机头为目标URL
rewrite: (path) => path.replace(/^\/api/, ''), // 重写请求的路径
}
}
}
})
//对应vue页面的get地址,前缀应该为/api,配置文件会重定向
const response = await axios.get('/api/example');