• 6、什么是跨域?跨域解决方案?


    参考:https://blog.csdn.net/qq_38128179/article/details/84956552

    一、为什么会出现跨域问题

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

     

    二、什么是跨域

    当一个请求url的协议、域名、端口三者之间任意一个与当前页面url不同即为跨域

    当前页面url 被请求页面url 是否跨域 原因
    http://www.test.com/ http://www.test.com/index.html 同源(协议、域名、端口号相同)
    http://www.test.com/ https://www.test.com/index.html 跨域 协议不同(http/https)
    http://www.test.com/ http://www.baidu.com/ 跨域 主域名不同(test/baidu)
    http://www.test.com/ http://blog.test.com/ 跨域 子域名不同(www/blog)
    http://www.test.com:8080/ http://www.test.com:7001/ 跨域 端口号不同(8080/7001)

     

     

     

     

     

     

     

    三、非同源限制

    (1)无法读取非同源网页的 Cookie、LocalStorage 和 IndexedDB

    (2)无法接触非同源网页的 DOM

    (3)无法向非同源地址发送 AJAX 请求

     

    四、服务端的跨域解决方案

    1、JSONP

    JSONP 是服务器与客户端跨源通信的常用方法。最大的特点是简单适用,兼容性好(兼容低版本IE),缺点是只支持 Get 请求,不支持 Post 请求。

    核心思想:网页通过添加一个 <script> 元素,向服务器请求JSON数据、服务器接收到请求后,将数据放在一个指定名字的回调函数的参数位置传回来。

    前端代码

    <!DOCTYPE html>
    <html lang="en">
        <head>
            <meta charset="UTF-8" />
            <meta http-equiv="X-UA-Compatible" content="IE=edge" />
            <meta name="viewport" content="width=device-width, initial-scale=1.0" />
            <title>JSONP</title>
            <script src="https://css.ssl.q1.com/jquery/jquery-1.11.1.min.js?v=2018051103"></script>
        </head>
        <body>
            <div id="btn">请求接口</div>
            <script>
                $('#btn').click(() => {
                    $.ajax({
                        async: true,
                        url: "http://xxxxxx.dev.q1op.com/home/test",
                        type: "GET",
                        dataType: "jsonp", // 返回的数据类型,设置为JSONP方式
                        jsonp: 'callback', //指定一个查询参数名称来覆盖默认的 jsonp 回调参数名 callback
                        jsonpCallback: 'handleResponse', //设置回调函数名
                        data: {
                            q: "javascript",
                            count: 1
                        },
                        success: function (response, status, xhr) {
                            console.log('状态为:' + status + ',状态是:' + xhr.statusText);
                            console.log(response);
                        }
                    });
                });
    
                function handleResponse()
                {
                    console.log('回调');
                }
            </script>
        </body>
    </html>
    View Code

    后端代码:

    namespace CorsTest.Controllers
    {
        [ApiController]
        [Route("[controller]")]
        public class HomeController : ControllerBase
        {
            [HttpGet("test")]
            public IActionResult Test(string callback)
            {
                return Content($"{callback}(ok)");
            }
        }
    }
    View Code

    执行结果:

     

    2、CORS

     CORS是跨域资源分享(Cross-Origin Resource Sharing)的缩写,他是W3C标准,属于跨源AJAX请求的根本解决方法。

      (1) 普通跨域请求:只需服务器端设置 Access-Control-Allow-Origin

      (2)带cookie跨域请求,前后端都需要进行设置。

    一个错误的案例

    在服务端代码中 public void ConfigureServices(IServiceCollection services) 定义跨域解决方案

    services.AddCors(options =>
    {
        options.AddPolicy("CorsAllowAll", (builder) =>
        {
            builder.AllowAnyOrigin() // 允许任意来源的主机访问
            .AllowAnyMethod()
            .AllowAnyHeader()
            .AllowCredentials();//处理 Cookie
        });
    });

    在 public void Configure(IApplicationBuilder app, IWebHostEnvironment env) 中 use上述方案(注 "CorsAllowAll" 可以定义为任何值,但需要上下一致)

    app.UseCors("CorsAllowAll");

    上述方案启动服务时会报错:

    解决方案:

      根据请求是否需要携带Cookie来修改跨域方案配置。

          (1)请求设置不携带 Cookie

              

                此时,服务端无需设置  AllowCredentials()         

    services.AddCors(options =>
    {
        options.AddPolicy("CorsAllowAll", (builder) =>
        {
            builder.AllowAnyOrigin() // 允许任意来源的主机访问
            .AllowAnyMethod()
            .AllowAnyHeader();
            //.AllowCredentials();//处理 Cookie (当前端的 xhrFields: { withCredentials: false } 参数设置为false时,无需处理 Cookie)
        });
    });

         (2)请求设置携带 Cookie

           

           此时,服务端需要 配置  AllowAnyOrigin()

    services.AddCors(options =>
    {
        options.AddPolicy("CorsAllowAll", (builder) =>
        {
            //这段解决 AllowAnyOrigin() 不能跟 AllowCredentials() 共用的问题
            builder = builder.SetIsOriginAllowed((host) => true);
    
            builder.AllowAnyMethod()
            .AllowAnyHeader()
            .AllowCredentials();//处理 Cookie (当前端的 xhrFields: { withCredentials: false } 参数设置为false时,无需处理 Cookie)
        });
    });

       此案例前端完整代码:

    <!DOCTYPE html>
    <html lang="en">
        <head>
            <meta charset="UTF-8" />
            <meta http-equiv="X-UA-Compatible" content="IE=edge" />
            <meta name="viewport" content="width=device-width, initial-scale=1.0" />
            <title>CORS</title>
            <script src="https://css.ssl.q1.com/jquery/jquery-1.11.1.min.js?v=2018051103"></script>
        </head>
        <body>
            <div id="btn">请求接口</div>
            <script>
                $('#btn').click(() => {
                    $.ajax({
                        url: "http://xxxxxxx.dev.q1op.com/home/test",
                        type: "get",
                        crossDomain: true,
                        contentType: 'application/json',
                        xhrFields: { withCredentials: true },
                        success: function (data) {
                            console.log(data)
                        },
                        error: function (data) {
                            console.log(data)
                        }
                    })
                });
            </script>
        </body>
    </html>
    View Code
  • 相关阅读:
    [ Algorithm ] N次方算法 N Square 动态规划解决
    [ Algorithm ] LCS 算法 动态规划解决
    sql server全文索引使用中的小坑
    关于join时显示no join predicate的那点事
    使用scvmm 2012的动态优化管理群集资源
    附加数据库后无法创建发布,error 2812 解决
    浅谈Virtual Machine Manager(SCVMM 2012) cluster 过载状态检测算法
    windows 2012 r2下安装sharepoint 2013错误解决
    sql server 2012 数据引擎任务调度算法解析(下)
    sql server 2012 数据引擎任务调度算法解析(上)
  • 原文地址:https://www.cnblogs.com/yxcn/p/15096242.html
Copyright © 2020-2023  润新知