跨域问题解决方案

1.为什么会出现跨域的问题

在Web开发中,跨域问题通常指的是浏览器出于安全考虑,限制了从一个源(domain, protocol, port)的网页去请求另一个源的资源。在前后端不分离的情况下,虽然前端可以通过JavaScript调用后端接口,但一旦后端接口是跨域的,浏览器就会阻止这个请求。这是因为浏览器遵循同源策略(Same-origin policy),它不允许来自一个源的网页脚本与另一个源的网页进行数据交互。

tips:前后端不分离的情况下,我们常用的方法就是前端js去调用后端接口,然后后端去调取跨域接口

2.常见的跨域方式

JsonP

JSONP(JSON with Padding)是一种利用<script>标签的跨域数据交互方式。因为<script>标签不受同源策略的限制,所以就可以通过动态创建<script>标签啦,在它的src属性中指定跨域URL来实现跨域数据请求。但JSONP只支持GET请求,并且存在安全风险。

复制代码
<!DOCTYPE html>  
<html lang="en">  
<head>  
    <meta charset="UTF-8">  
    <title>JSONP Example</title>  
</head>  
<body>  
  
<script>  
    function handleResponse(data) {  
        console.log(data); // 输出: { Name: "John Doe", Age: 30 }  
    }  
  // 创建一个新的script标签  
    var script = document.createElement('script');  
// 设置script标签的src属性为跨域URL,并附带一个回调函数名  
    script.src = 'https://your-backend-url/api/jsonp?callback=handleResponse';  
// 将script标签添加到DOM中,浏览器会发起跨域请求  
    document.body.appendChild(script);  
</script>  
  
</body>  
</html>

后端代码

复制代码
[HttpGet("jsonp")]  
public IActionResult Jsonp(string callback)  
{  
    var data = new { Name = "John Doe", Age = 30 };  
    var jsonpCallback = HttpContext.Request.Query["callback"].ToString();  
    var jsonpResult = $"{jsonpCallback}({Newtonsoft.Json.JsonConvert.SerializeObject(data)})";  
    return Content(jsonpResult, "application/javascript");  
}

添加请求头实现跨域

通常指的是后端服务器在响应头中添加一些特定的字段(如Access-Control-Allow-Origin),来告诉浏览器这个响应允许哪些源的请求。但是,这种方式需要后端服务器的支持,并且只能由后端来配置。

复制代码
public class CustomCorsMiddleware  
{  
    private readonly RequestDelegate _next;  

    public CustomCorsMiddleware(RequestDelegate next)  
    {  
        _next = next;  
    }  

    public async Task InvokeAsync(HttpContext context)  
    {  
        context.Response.Headers.Add("Access-Control-Allow-Origin", "http://example.com");  
        // 其他可能的跨域头...  

        await _next(context);  
    }  
}  

// 在 Startup.cs 的 Configure 方法中注册中间件  
app.UseMiddleware<CustomCorsMiddleware>();

高效CORS

CORS(Cross-Origin Resource Sharing)是W3C推荐的一种跨域资源共享方案,通过浏览器和服务器之间的通信来确定是否允许跨域请求。在.NET Core中,我们可以很方便地使用CORS中间件来实现跨域。

在.NET Core 8中使用CORS

在.NET Core 8(或任何支持CORS的.NET Core版本)中,你可以通过以下步骤来配置CORS:

1. 注入CORS服务

在Startup.cs的ConfigureServices方法中,你需要注入CORS服务并定义跨域策略。

复制代码
public void ConfigureServices(IServiceCollection services)  
{  
    // ... 其他服务注入 ...  
  
    // 跨域配置  
    //方法1
    services.AddCors(options =>  
    {  
        options.AddPolicy("LimitRequests", policy =>  
        {  
            policy  
                .WithOrigins("http://example1.com", "http://example2.com") // 允许的源  
                .AllowAnyHeader() // 允许任何头  
                .AllowAnyMethod(); // 允许任何方法  
        });  
    });  
    
    
  
    // ... 其他代码 ...  
}

2. 在管道中启用CORS中间件

在Startup.cs的Configure方法中,你需要确保在调用其他中间件(如app.UseMvc()或app.UseRouting())之前启用CORS中间件。

复制代码
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)  
{  
    // ... 其他中间件配置 ...  
  
    // 启用CORS中间件  
    app.UseCors("LimitRequests"); // 使用前面定义的策略名称  
  
    // ... 路由和MVC中间件 ...  
    app.UseRouting();  
    app.UseEndpoints(endpoints =>  
    {  
        endpoints.MapControllers(); // 或其他路由配置  
    });  
  
    // ... 其他代码 ...  
}

注意事项

  • 我们一般建议不在生产环境中去用AllowAnyOrigin、AllowAnyHeader或AllowAnyMethod,这会增加应用面临安全风险的概率。要明确指定允许的源、头和方法。
  • 如果你的应用使用了其他中间件(如MVC、路由、重定向等),确保CORS中间件在它们之前被调用,否则跨域请求可能会失败。
  • 如果你在使用认证/授权中间件(如JWT),并且允许跨域携带凭据(通过设置AllowCredentials()),确保你的CORS策略中指定的源和你的身份验证服务器配置相匹配。
相关推荐
叫我一声阿雷吧3 分钟前
JS 入门通关手册(45):浏览器渲染原理与重绘重排(性能优化核心,面试必考
javascript·前端面试·前端性能优化·浏览器渲染·浏览器渲染原理,重排重绘·reflow·repaint
大家的林语冰13 分钟前
《前端周刊》尤大开源 Vite+ 全家桶,前端工业革命启动;尤大爆料 Void 云服务新产品,Vite 进军全栈开发;ECMA 源码映射规范......
前端·javascript·vue.js
清心歌21 分钟前
CopyOnWriteArrayList 实现原理
java·开发语言
jiayong2330 分钟前
第 8 课:开始引入组合式函数
前端·javascript·学习
田八34 分钟前
聊聊AI的发展史,AI的爆发并不是偶然
前端·人工智能·程序员
Java成神之路-43 分钟前
通俗易懂理解 Spring MVC 拦截器:概念、流程与简单实现(Spring系列16)
java·spring·mvc
zhanghongbin0144 分钟前
AI 采集器:Claude Code、OpenAI、LiteLLM 监控
java·前端·人工智能
计算机毕设vx_bysj68691 小时前
【免费领源码】77196基于java的手机银行app管理系统的设计与实现 计算机毕业设计项目推荐上万套实战教程JAVA,node.js,C++、python、大屏数据可视化
java·mysql·智能手机·课程设计
忘梓.1 小时前
墨色规则与血色节点:C++红黑树设计与实现探秘
java·开发语言·c++
hhh3u3u3u1 小时前
Visual C++ 6.0中文版安装包下载教程及win11安装教程
java·c语言·开发语言·c++·python·c#·vc-1