zoukankan      html  css  js  c++  java
  • 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
  • 相关阅读:
    怎么样通过API函数获取tooltip的内容(请高手帮忙)
    Ajax控件之Accordion控件学习
    C#中结构与类的区别
    C# ref and out 区别
    java 将PDF文件的首页提取为图片
    围住浮动元素(消除浮动)的三种方法
    myeclipse unable to install breakpoint
    C#调用C++编写的COM DLL
    高手教你玩53kf在线客服的指定客服功能
    让IIS支持Flv的详细设置方法
  • 原文地址:https://www.cnblogs.com/yxcn/p/15096242.html
Copyright © 2011-2022 走看看