ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

.Net Core 后台 + Apisix 网关 解决跨域访问Cors问题

2022-02-18 18:33:31  阅读:351  来源: 互联网

标签:baidu Core 网关 http 跨域 www com 请求


1, 什么是跨域

浏览器从一个域名的网页去请求另一个域名的资源时,域名、端口、协议任一不同,都是跨域
域名:
 主域名不同 http://www.baidu.com/index.html -->http://www.sina.com/test.js
 子域名不同 http://www.666.baidu.com/index.html -->http://www.555.baidu.com/test.js
 域名和域名ip http://www.baidu.com/index.html -->http://180.149.132.47/test.js
端口:
 http://www.baidu.com:8080/index.html–> http://www.baidu.com:8081/test.js
协议:
 http://www.baidu.com:8080/index.html–> https://www.baidu.com:8080/test.js
备注:
 1、端口和协议的不同,只能通过后台来解决
 2、localhost和127.0.0.1虽然都指向本机,但也属于跨域

当发生跨域访问(cross-domain access),浏览器就无法正常从后台服务中获取信息。所以必须要解决跨域问题。

 

2,跨域的种类

浏览器将CORS请求分成两类:简单请求(simple request)非简单请求(not-so-simple request)。

只要同时满足以下两大条件,就属于简单请求。

(1) 请求方法是以下三种方法之一:

HEAD
GET
POST

(2)HTTP的头信息不超出以下几种字段:

Accept
Accept-Language
Content-Language
Last-Event-ID
Content-Type:只限于三个值 
    application/x-www-form-urlencoded(对发送内容进行编码)
    multipart/form-data(上传的表单内包含文件)
    text/plain(发送内容为纯文本格式)

凡是不同时满足上面两个条件,就属于非简单请求。

 

对于简单请求,浏览器直接发出CORS请求。具体来说,就是在头信息之中,增加一个Origin字段。

Origin: http://api.bob.com
Host: api.alice.com
Accept-Language: en-US
Connection: keep-alive
User-Agent: Mozilla/5.0…

上面的头信息中,Origin字段用来说明,本次请求来自哪个源(协议 + 域名 + 端口)。服务器根据这个值,再根据自身的跨域设置,决定是否同意这次请求。

如果Origin指定的源,不在许可范围内,服务器会返回一个正常的HTTP回应。浏览器发现,这个回应的头信息没有包含Access-Control-Allow-Origin字段(详见下文),就知道出错了,从而抛出一个错误,被XMLHttpRequestonerror回调函数捕获。注意,这种错误无法通过状态码识别,因为HTTP回应的状态码有可能是200。

 

对于非简单请求的CORS请求,会在正式通信之前,不需要用户操作,浏览器自动发送一个OPTION请求(也叫做预检操作)。

服务器收到预检请求后,检查这些特殊的请求方法和头自己能否接受。如果服务器支持预检中的Header和Methods,那么接下来就可以正常发送信息。

 

3,跨域的解决方案

跨域问题可以从三个方面着手解决:前端/后端/网关

前端很多的解决方案,例如Vue的话可以试试:axios解决跨域问题(vue-cli3.0)

.Net Core 3.1 的后端的解决方法也比较简单,最懒的方法是在Startup.cs的Configure方法增加以下代码:

   app.UseCors(builder =>
            {
                builder.AllowAnyMethod()
                    .AllowAnyHeader()
                    .SetIsOriginAllowed(_ => true) // =AllowAnyOrigin()
                    .AllowCredentials();
            });

将上述代码插入到 app.UseRouting() 与 app.UseCors之间,则在全局范围内取消了一切跨域访问的限制。

或者,在ConfigureServices方法添加跨域设置,然后在Configure方法使用这个跨域设置也可以:

//ConfigureServices 设置允许所有来源跨域
            services.AddCors(options => options.AddPolicy("CorsPolicy",
            builder =>
            {
                builder.AllowAnyMethod()
                    .AllowAnyHeader()
                    .SetIsOriginAllowed(_ => true) // =AllowAnyOrigin()
                    .AllowCredentials();
            }));



//Configure 使用跨域配置
            app.UseCors("CorsPolicy");

 

如果不想全局都一个跨域的设置,而是每一个Controller设置每一个方法都有特定的跨域设置,则可以在Startup.cs文件的方法用AddCors方法添加若干个跨域设置,然后在对应的Controller或者方法上使用 [EnableCors] 属性启用 CORS。

详情可以参考微软官方文档:在 ASP.NET Core 中启用跨源请求 (CORS)

 

对于后台服务来说,一般都要配备网关。我这个项目选用了国人开源的Apisix网关。Apisix的使用就不啰嗦了,反正友好的文档以及方便的Dashboard,相当的不错。

前面说过,跨域请求的“非简单请求”会首先发送一次OPTION请求(预检操作)到服务器,等待服务器告知正常才正式执行请求。所以,务必务必,在网关设置允许的HTTP方法里,添加选择OPTION

 

 如果后端已经开启了CORS,则网关除了HTTP方法外无需留意其他的设置。但如果后端不设置的话,网关也一样能解决跨域访问:

我们在Apisix网关的路由配置页面的第三步“插件配置”里可以发现一个Cors,只需要将其启用即可:

 

 相关的配置,Apisix也有详细的文档说明:cors

 

 

 

4,参考链接:

什么是跨域?如何解决跨域问题?

CORS简单请求和非简单请求

CORS请求的简单请求和非简单请求

 

标签:baidu,Core,网关,http,跨域,www,com,请求
来源: https://www.cnblogs.com/AlvinLiang/p/15910902.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有