跨域方式

作者: 糕糕AA | 来源:发表于2019-07-02 19:37 被阅读0次

    同源策略:不同源的是不能进行请求等操作的,只要满足 协议、主机、端口 一致,则两个页面具有相同的源

    跨域:跨域是不可能靠前端单方面解决,总是需要服务器的支持

    跨域情况:1、同一父域的子域之间;2、不同父域之间;3、端口不同;4、协议不同

    • 3、4需要通过Proxy:发起方的域下创建Proxy程序,发起方的域下调用Proxy,Proxy将请求发送给接收方并获取相应数据,Proxy将获得数据返回给发起的js

    1、document.domain+iframe
    (只能解决1):在发起和接收方设置document.domain,并设置为父域的主域名(window.location.hostname);发起方页面创建隐藏的iframe,iframe的源是接收方页面;根据浏览器的不同,通过iframe.contentDocument || iframe.contentWindow.document来获得接收方页面的内容;通过接收方页面的内容与接收方进行交互。(缺点:当一个域被攻击,另一个域有安全漏洞出现)

    2、jsonp

    • HTML标签中src和href属性可以请求外部地址,没有跨域限制,根据src这一特性,得到jsonp的跨域请求方式
    • 通过动态添加<script>的标签,可控的去请求远端js并执行
    • 与服务器约定好一个回调函数,服务器收到请求返回一段js,这段js中调用约定好的回调函数,并将数据作为作为参数传递。网页收到这段js代码,执行回调,数据成功返回。
    • jsonp缺点:只支持get方式,脚本注入行为存在安全隐患。

    (1)代码实现:

    var script = document.createElement('script'); // 创建script标签
    script.type = 'text/javascript';  // 设置type
    // 传参并指定回调执行函数为onBack
    script.src = 'http://www.domain2.com:8080/login?user=admin&callback=onBack'; // 设置src,要访问的地址。提供jsonp服务的url地址(不管是什么类型的地址,最终生成的返回值都是一段javascript代码)
    document.head.appendChild(script); // 将标签插入文档头部
    // 回调函数
    function onBack(res) {  // 设置回调函数,获取返回的数据,并处理
        alert(JSON.stringify(res));
    }
    //服务端返回如下(返回时即执行全局函数):
    onBack({"status": true, "user": "admin"}) 
    

    (2)jquery ajax:

    $.ajax({
        url: 'http://www.domain2.com:8080/login',
        type: 'get',
        dataType: 'jsonp',  // 请求方式为jsonp
        jsonpCallback: "onBack",    // 自定义回调函数名
        data: {}
    });
    

    3、Proxy解决跨域问题:

    • 开发 webpack proxy-middleware代理
    • proxy 的工作机制是:你依然请求本地地址,即使你 npm run dev 跑起来的东西并没有任何接口能力,而 Webpack 后台会将所有指定的请求转发到 target 对应的地址上。这个转发的过程发生在服务端(也就是 webpack-dev-server),所以浏览器是不知道的。
          proxy: {
               '/api': {
                 target: 'https://list.jd.com/list.html?cat=1318,1462,1480&callback=jQuery942326&md=9&l=jdlist&go=0',
                 pathRewrite: {'^/api' : ''},
                 changeOrigin:true, //必须要加,否则是访问自己
                }
            }
    
    • 生产 nginx代理
      * 生产环境 配置nginx.conf
      js
             location /api {
                        # 这里也可以录用原有参数,进行复用,并重写URL
                        proxy_pass https://list.jd.com/list.html?cat=1318,1462,1480&callback=jQuery942326&md=9&l=jdlist&go=0;
                    }
    

    4、 cors:需要与服务端配合

    • “跨域资源共享”,允许浏览器向跨源服务器,发出XMLHttpRequest请求,从而克服了AJAX只能同源使用的限制。
    • 同源策略不仅在浏览器有限制,在服务端也有限制
    • 简单请求:方法为HEAD、GET或者POST中的一种;HTTP的头信息不超过以下几种字段Accept、Accept-Language、Content-Language、Last-Event-ID以及Content-Type的值只限于application/x-www-form-urlencoded、multipart/form-data、text/plain三个
      简单请求时,浏览器会自动在请求头中添加一个字段Origin,值为发出请求网页的源地址。服务端根据这个值,决定是否同意这次请求,如果Origin的值不在指定的许可范围,服务端返回一个正常的HTTP回应。浏览器未找到Access-Control-Allow-Origin字段,则抛出错误,但这个错误无法通过状态吗识别
    • 非简单请求:PUT或DELETE,或者Content-Type字段的类型是application/json。浏览器会在正式请求之前发送一次预检请求,option`请求。正式请求之前,浏览器会去问服务端我这个地址能不能访问你,如果可以,浏览器才会发送正式的请求,否则报错。
    • 总的来说:CORS实现跨域的方法就是根据请求头的Origin值和响应头的Access-Control-Request-Headers和Access-Control-Request-Method的值进行比对,通过了就可以请求成功,没通过就请求失败。

    JSONP只支持GET请求,CORS支持所有类型的HTTP请求。JSONP的优势在于支持老式浏览器,以及可以向不支持CORS的网站请求数据。

    反向代理:node,Nginx

    同源策略只是浏览器的一个安全策略,只适用于浏览器向服务器发送请求的时候,当服务器跟服务器发送请求的时候,自然就没有这么一层限制,只要是接口,就会返回。

    权限不通过的时候,也是会请求成功200的,只是返回的是“需要登录”等信息

    • 正向代理:客户端知道谁是真正返回数据的服务器
    • 反向代理:客户端不知道谁是返回数据的服务器

    相关文章

      网友评论

        本文标题:跨域方式

        本文链接:https://www.haomeiwen.com/subject/otnthctx.html