.net core的允许跨域访问三个问题解决

一,我们看看什么是跨域
我们可以理解页面发起当一个请求 url 的协议、域名、端口三者之间任意一个与当前页面 url 不同即为跨域。那为什么会出现跨域问题呢?

 

二,我们先理解跨域的结果是怎样的

如下图结果:

 

 而浏览器提示错误,如下图

 由上图我们可以得出结论,其实服务器是返回成功的200,跨域的结果其实是浏览器限制了你的请求

 

三,那为什么浏览器会限制呢?

由于浏览器的同源策略限制,同源策略(Sameoriginpolicy)是一种约定,它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,则浏览器的正常功能可能都会受到影响。
可以说 Web 是构建在同源策略基础之上的,浏览器只是针对同源策略的一种实现。同源策略会阻止一个域的 javascript 脚本和另外一个域的内容进行交互。所谓同源(即指在同一个域)就是两个页面具有相同的协议(protocol),主机(host)和端口号(port)

 

四,那在.net core我们怎么解决跨域问题呢,这个时候我们的cors就出场了,我们看下微软官方文档看下cors的解释

 

五,看下我们的代码实现三种类型
1》跨源(cross-origin)不带请求证书(Credentials)

 js方法如下

      $("#btn1").click(function () {
            //alert(11);
            $.ajax({
                url: 'http://localhost:8000/Home/Get',
                type: 'Get',
                success: function (res) {
                    alert(res.name);
                }
            });
        })

请求结果如下

 这个*号是AllowAnyOrigin,设置返回的,返回是允许所有源的意思,如下代码

            #region 普通的跨域验证,不带请求中的证书

            app.UseCors(builder =>
            {
                builder.AllowAnyOrigin()
                       .AllowAnyHeader()
                       .AllowAnyMethod()
                       .SetPreflightMaxAge(TimeSpan.FromSeconds(2000000));
            });
            #endregion

 
2》跨源(cross-origin)带请求证书(Credentials)

 

        $("#btn2").click(function () {
            //alert(11);
            $.ajax({
                url: 'http://localhost:8000/Home/Get',
                type: 'Get',
                xhrFields: { withCredentials: true },
                crossDomain: true,
                success: function (res) {
                    alert(res.name);
                }
            });
        })

 

我们使用第二种请求方式,而这个时候如果我们开启了,却没有改后端配值,我们发起请求发现。回报如下跨域:Access to XMLHttpRequest at 'http://localhost:8000/Home/Get' from origin 'http://localhost:5000' has been blocked by CORS policy: The value of the 'Access-Control-Allow-Origin' header in the response must not be the wildcard '*' when the request's credentials mode is 'include'. The credentials mode of requests initiated by the XMLHttpRequest is controlled by the withCredentials attribute.

这个是什么原因导致的呢?我们看看ajax请求,因为我们使用了 withCredentials: true,而恰恰这个使用是不允许AllowAnyOrigin()的,意思就是不允许返回的Access-Control-Allow-Origin:*,那我们的处理方式如下

我们看看的配置,如下代码,我们必须开启AllowCredentials,同时去掉AllowAnyOrigin,这两个

            #region 跨源(cross-origin)请求中的证书(Credentials) 不带自定义参数
            ////当在ajax设置了withCredentials: true,就是要带域名的cookie,同时这里是不允许返回Access - Control - Allow - Origin: *这个带星号的,这个时候,我们就要设置允许的参数了

            app.UseCors(builder =>
            {
                builder.SetIsOriginAllowed(_ => true)
               .AllowCredentials();
            });

            #endregion

 这个时候我们看看请求结果到底有什么区别,如下图

 发现我们的请求head多了了Access-Control-Allow-Credentials:true和带了cookie

 

3》跨源(cross-origin)带请求证书(Credentials)+自定义head参数

如果我们在请求头加自定义参数,我们这个时候又会提示跨域,如下js方法如下

   $("#btn3").click(function () {
            //alert(11);
            $.ajax({
                url: 'http://localhost:8000/Home/Get',
                type: 'Get',
                headers: {
                    'content-type': 'application/json;charset=UTF-8',
                    'test': "123",
                    'authorization': '456'
                },
                xhrFields: { withCredentials: true },
                crossDomain: true,
                success: function (res) {
                    alert(res.name);
                }
            });
        })

 如下图错误:Access to XMLHttpRequest at 'http://localhost:8000/Home/Get' from origin 'http://localhost:5000' has been blocked by CORS policy: Request header field test is not allowed by Access-Control-Allow-Headers in preflight response.

 

 这是为什么呢?这个是时候就是我们必须在后端代码配置请求头参数,如下代码

   #region    #region 跨源(cross-origin)请求中的证书(Credentials)+ 带自定义参数
            ////当在ajax设置了withCredentials: true,就是要带域名的cookie,同时这里是不允许返回Access - Control - Allow - Origin: *这个带星号的,这个时候,我们就要设置允许的参数了
            app.UseCors(builder =>
            {
                builder.WithHeaders("authorization", "test", "content-type") //如果开启带检验,并且ajax的headers头部自带自定义参数时。必须带上自定义的
                       .SetIsOriginAllowed(_ => true)
                      .AllowCredentials();
            });
            #endregion

这个时候我们看看请求的请求头,如下

我们也要在后端添加上如下几个接受,才是不提示跨域的问题 !!!

 当然,如果不想设置参数,我们可以允许所有的头

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

为了安全我们可以设置固定的域名,来源

            app.UseCors(builder =>
            {
                builder.WithOrigins("http://localhost:5000")
                      .AllowCredentials()
                      .AllowAnyHeader();
            });

 

posted @ 2020-11-12 17:40  叶丶梓轩  阅读(7419)  评论(0编辑  收藏  举报