资讯专栏INFORMATION COLUMN

前端跨域方法总结

PAMPANG / 2505人阅读

摘要:是的,方法被调用时,会在所有页面脚本执行完毕之后向目标窗口派发一个消息。该消息有四个属性需要注意属性表示该的类型属性为的第一个参数属性表示调用方法时调用页面的当前状态属性记录调用方法的窗口信息。

1.为什么要跨域

同源策略限制一个源加载的文档或文档与来自另一个源的资源进行交互。这是一个用于隔离潜在恶意文件的安全机制。
什么是同源呢? 如果协议,端口(如果指定了一个)和域名对于两个页面是相同的,则两个页面具有相同的源。
下表给出了相对http://store.company.com/dir/...同源检测的示例:

跨域网络访问通常分为3种

通常允许进行跨域写操作(Cross-origin writes)。例如链接(links),重定向以及表单提交。特定少数的HTTP请求需要添加 preflight。

通常允许跨域资源嵌入(Cross-origin embedding)。

通常不允许跨域读操作(Cross-origin reads)。但常可以通过内嵌资源来巧妙的进行读取访问。例如可以读取嵌入图片的高度和宽度,调用内嵌脚本的方法。
另外,同源策略约束了XMLHttpRequest,也就是说ajax进行跨域访问会报错。

2.跨域的解决方式
2.1 window.name

原理: 再浏览器中打开一个页面中,或用iframe打开一个页面时会创建一个window对象,当页面加载一个新的页面时,window.name属性是不会变的,因此我们可以在页面中动态创建一个iframe页面指向另一个域,将数据赋值个window.name属性。(值得注意的是,此时我们无法直接访问window.name),我们还需要将将iframe的src指向相同域的空白页面。之后再将iframe删除就可以了

//http://localhost:3000/request.js
     function CreateIframe(src, nextsrc){
        var iframe = document.createElement("iframe");
        var flag = true;
        iframe.src = src;
        iframe.style.display = "none";
        iframe.onload = function(){
            if(flag){
                iframe.src = nextsrc;
                flag = false;
            }else{
                p.innerHTML = iframe.contentWindow.name;
                iframe.contentWindow.close();
                document.body.removeChild(iframe);
                iframe.src = "";
                iframe = null
            };
        };
        document.body.appendChild(iframe);
    }

 CreateIframe("http://localhost:3001/a.html", "http://localhost:3000/b.html");
//http://localhost:3001/response.js
        function ajax(url, method){
            const xhr = new XMLHttpRequest();
            xhr.onload = function(data){
                 window.name = this.responseText
                 console.log(window.name);
            }
            xhr.open(method, url, true);
            xhr.send(null);
        }
        ajax("http://localhost:3001/req", "GET");
2.2 document_domain

原理:通过该document.domain来设置域名,但是有局限性,也就是一级域名一致才可以。

//http://localhost:3000/request.js
 document.domain = "http://localhost:3001";
 document.getElementById("iframe").onload = function(){
      var win = iframe.contentWindow;
      var doc = win.document;
      console.log(win.data);
 }
//http://localhost:3001/response.js
        document.domain = "http://localhost:3001";
        var data = "123";
2.3 JSONP

原理: JSONP实现跨域请求的原理简单的说,就是动态创建

//jsonp.js
const Jsonp = (() => {
    function jsonp(url, handle){
        let script = document.createElement("script");
        script.setAttribute("src", `${url}?callback=${handle}`);
        document.body.appendChild(script);
    }
    return jsonp;
})()
//server.js
app.get("/", function (req, res) {
    var callbackName = req.query.callback;   // myFunction
    res.send(callbackName+"({"message": "It is JSONP!"});");
})
2.4 HTML5PostMessage

PostMessage是HTML5的API,postMessage() 方法被调用时,会在所有页面脚本执行完毕之后向目标窗口派发一个 MessageEvent 消息。 该MessageEvent消息有四个属性需要注意: message 属性表示该message 的类型; data 属性为 window.postMessage 的第一个参数;origin 属性表示调用window.postMessage() 方法时调用页面的当前状态; source 属性记录调用 window.postMessage() 方法的窗口信息。
只有通过其他窗口的一个引用,比如iframe的contentWindow属性、执行window.open返回的窗口对象、或者是命名过或数值索引的window.frames。才能使用

////http://localhost:3000/request.js
    var popup =window.open("http://localhost:3001/index4.html");
        function receive(event){
            if(event.origin !== "http://localhost:3001") return;
            document.querySelector("#message").innerHTML = event.data;
        }
        window.addEventListener("message", receive, false);
//http://localhost:3001/response.js
    var popup = window.opener;
        popup.postMessage("发送消息", "http://localhost:3000/");
        window.addEventListener("message", (e) => {
            if(e.origin !== "http://localhost:3001") return;
            document.querySelector("#message").innerHTML = e.data;
            //e.source.postMessage("发送消息", e.origin);
        }, false)
2.4 CORS

cors主要靠服务器,只要服务器实现了cors接口,就可以跨源通信。具体的原理可以看阮老师的文章跨域资源共享 CORS 详解

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/84873.html

相关文章

  • 2018年腾讯前端一面总结(面向2019届学生)

    摘要:前言腾讯一面,相比阿里一面来说,腾讯一面先给打电话预定时间,这也给了我们这些面试者去准备的时间。其实闭包也就是指有权访问另一个函数作用域的函数而已。常用的创建闭包的方法就是在函数内部创建另一个函数。 前言 腾讯一面,相比阿里一面来说,腾讯一面先给打电话预定时间,这也给了我们这些面试者去准备的时间。但是也正是因为这种确定性,也有在等待电话的时候的心情的忐忑。 背景 我是一名大三学生,大一...

    Kosmos 评论0 收藏0
  • 总结系列〕前端面试题精华筛选

    摘要:所谓同源是指协议域名端口三者相同,即便两个不同的域名指向同一个地址,也非同源。那么怎样解决跨域问题的呢通过跨域跨域跨域跨域跨域资源共享代理跨域中间件代理跨域音乐教程老师有用到协议跨域后端在头部信息里面设置安全域名公司后端给解决过持续更新中 JavaScript篇 如何获取浏览器URL中查询字符串中的参数? 1.封装方法 getUrlArgs(url) { const args =...

    lyning 评论0 收藏0
  • 总结系列〕前端面试题精华筛选

    摘要:所谓同源是指协议域名端口三者相同,即便两个不同的域名指向同一个地址,也非同源。那么怎样解决跨域问题的呢通过跨域跨域跨域跨域跨域资源共享代理跨域中间件代理跨域音乐教程老师有用到协议跨域后端在头部信息里面设置安全域名公司后端给解决过持续更新中 JavaScript篇 如何获取浏览器URL中查询字符串中的参数? 1.封装方法 getUrlArgs(url) { const args =...

    Thanatos 评论0 收藏0
  • 前端秋招面试总结

    摘要:前言秋招宣告结束,面试了接近家公司,有幸拿到,感谢这段时间一起找工作面试的朋友和陪伴我的人。一定要提前准备好,不然面试官叫你说遇到的难点,或者直接问问题时可能会懵逼。 前言 秋招宣告结束,面试了接近20家公司,有幸拿到offer,感谢这段时间一起找工作面试的朋友和陪伴我的人。这是一段难忘的经历,相信不亚于当年的高考吧,也许现在想起来高考不算什么,也许只有经历过秋招的人才懂得找工作的艰辛...

    Gu_Yan 评论0 收藏0
  • 前端秋招面试总结

    摘要:前言秋招宣告结束,面试了接近家公司,有幸拿到,感谢这段时间一起找工作面试的朋友和陪伴我的人。一定要提前准备好,不然面试官叫你说遇到的难点,或者直接问问题时可能会懵逼。 前言 秋招宣告结束,面试了接近20家公司,有幸拿到offer,感谢这段时间一起找工作面试的朋友和陪伴我的人。这是一段难忘的经历,相信不亚于当年的高考吧,也许现在想起来高考不算什么,也许只有经历过秋招的人才懂得找工作的艰辛...

    Scholer 评论0 收藏0

发表评论

0条评论

PAMPANG

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<