业界动态
js 跨域(JSONP/CORS/WebSocket/postMessage/location.hash/document.domain/window.name)
2025-01-03 13:26

目录

前言

一、跨域

1、跨域的产生

二、解决跨域

1、具备src的标签

2、JSONP

3、CORS

4、WebSocket 协议(★★★★★

(1)、WebSocket 协议的特点

(2)、WebSocket 协议客户端的 API

5、postMessage(★★★★★

6、location.hash

7、document.domain

8、window.name

三、其他

1、反向代理

2、只针对Chrome的跨域解决办法

(1)、windows 操作系统

(2)、MAC OS 操作系统

四、对跨域的进一步学习

五、特殊的跨域


一篇优秀的文章:Javascript学习总结(二)——延迟对象、跨域、模板引擎、弹出层、AJAX示例 - 张果 - 博客园

同源策略:同协议、同域名、同端口。

同源策略限制以下几种行为

  • cookie、LocalStorage 和 IndexDB 无法读取。
  • DOM 和 Js对象无法获得。
  • AJAX 请求不能发送。

不遵守同源策略的通信就会产生跨域。

原理:所有具有属性的HTML标签都是可以跨域的

在浏览器中,、、和这几个标签是可以加载跨域(非同源)的资源的,并且加载的方式其实相当于一次普通的GET请求,唯一不同的是,为了安全起见,浏览器不允许这种方式下对加载到的资源的读写操作,而只能使用标签本身应当具备的能力(比如脚本执行、样式应用等等)。

JSONP(JSON with padding,填充式 JSON 或参数式 JSON)看起来与 JSON 差不多,只不过是被包含在函数调用中的 JSON。

 

JSONP 由两部分组成:回调函数 和 数据。回调函数是当响应到来时应该在页面中调用的函数,回调函数的名字一般是在请求中指定的。而数据就是传入回调函数中的 JSON  数据。下面是一个典型的 JSONP 请求

 

JSONP 的原理是动态插入 <script> 标签,通过<script> 标签的 src 特性引入一个 js 文件,当这个 js 文件载入成功时会执行我们在 url 参数中指定的回调函数,并且会把我们需要的 json 数据作为参数传入。

 

优点是:兼容性好,简单易用,支持 浏览器与服务器之间的双向通信。

缺点是

  • 只支持 GET 请求。
  • JSONP 是从别的域加载代码执行,如果别的域不安全,很可能会在响应中夹带一些恶意的代码,而此时除了完全放弃使用 JSONP 调用之外,没有办法追究。
  • 要确定 JSONP 是否失败很麻烦,虽然 HTML5 给 <script> 元素新增了一个 error 事件处理程序,但目前没有得到任何浏览器的支持。为此开发人员不得不使用计时器检测指定的时间内是否接收到了响应。就算这样也不尽人意,毕竟不是每个用户上网的速度和宽带都一样。

由于 JSONP 存在这样大的缺点,所以,现在已经没有使用 JSONP 的必要了,其他方法不能跨域的 JSONP 一样不能跨,其他方法要修改服务器端的 JSONP 一样要修改。

CORS(Cross-Origin Resource Sharing,跨域资源共享)定义了在必须访问跨域资源时,浏览器与服务器应该如何沟通。

CORS 的基本思想是使用自定义的 HTTP 头部让浏览器与服务器进行沟通,从而决定请求或响应是否成功。

比如一个简单的使用 GET 或 POST 发送的  Ajax 请求,需要给它附加一个额外的 Origin 头部,其中包含请求页面的源信息(协议、域名和端口)。以便服务器根据这个头部信息来决定是否给予响应。下面是 Origin 头部的示例

 

如果服务器认为请求可以接受,就在 Access-Control-Allow-Origin 头部回发相同的源信息(如果是公共资源,可以回发 “*”)。例如

 

如果没有这个头部,或者有这个头部但源信息不匹配,浏览器就会驳回请求。 

【传送门:Ajax 的详细知识与案例,请戳:js Ajax_weixin79893765432...的博客-CSDN博客_js,ajax】

除 IE 之外的浏览器以及苹果和安卓都支持 XHR(XMLHttpRequest)类型对 CORS 的实现。IE8 中引入了 XDR(XDomainRequest)类型,用 XDR 实现了类似 XHR 的功能。因为不同浏览器对 CORS 的支持不一样,所以就有了跨浏览器的 CORS

 

Firefox、Safari 和 Chrome 中的 XHR 对象与 IE 中的 XDR 对象类似,都提供了够用的接口,他们共同的属性和方法如下

  • responseText 属性:用于取得响应的内容。
  • abort() 方法:用于停止正在的请求。
  • send() 方法:用于发送请求。
  • error 事件:用于替代 onreadystatechange 检测错误。
  • load 事件:用于替代 onreadystatechange 检测成功。

以上成员都包含在 createCORSRequest() 函数返回的对象中,在所有浏览器中都能正常使用。

HTTP 协议有一个缺陷:通信只能由客户端发起。这种单向请求的特点,注定了如果服务器有连续的状态变化,客户端要获知就非常麻烦。我们只能使用“轮询”——每隔一段时候,就发出一个询问,了解服务器有没有新的信息。最典型的场景就是聊天室。但是轮询的效率低,非常浪费资源。因此,工程师们一直在思考,有没有更好的方法。WebSocket 就是这样发明的。

Websocket 是 HTML5 新增的一种 “全双工通信协议”——客户端和服务端基于 TCP 握手连接成功后,两者之间就可以建立持久性的连接,实现双向数据传输。

(1)、WebSocket 协议的特点

  • 建立在 TCP 协议之上,服务器端的实现比较容易。
  • 与 HTTP 协议有着良好的兼容性。默认端口也是 80 和 443,并且握手阶段采用 HTTP 协议,因此握手时不容易屏蔽,能通过各种 HTTP 代理服务器。
  • 数据格式比较轻量,性能开销小,通信高效。
  • 可以发送文本,也可以发送二进制数据。
  • 没有同源限制,客户端可以与任意服务器通信。
  • 协议标识符是 ws(如果加密,则为wss,服务器网址就是 URL。
 

只有支持 WebSocket 协议的服务器才能识别 ws 和 wss 标识符,才能正常工作。

(2)、WebSocket 协议客户端的 API

①、用 WebSocket 构造函数创建它的实例

WebSocket 对象作为一个构造函数,用于新建 WebSocket 实例,参数是一个 URL(注意:HTTP 协议的 URL 可以相对可以绝对,但是 WebSocket 协议的 URL 必须是绝对路径)。

 

由于 WebSocket 协议 不受同源策略对的限制,所以,可以通过它访问任何站点的链接,至于是否会跨域通信,则完全取决于服务器。

②、建立 WebSocket 链接

实例化 WebSocket 对象后,浏览器马上尝试创建连接,WebSocket 的实例上有一个 readyState 属性,该属性返回实例对象的当前状态,共有四种。

  • WebSocket.CONNECTING:值为 0,表示正在连接。
  • WebSocket.OPEN:值为 1,表示连接成功,可以通信了。
  • WebSocket.CLOSING:值为 2,表示连接正在关闭。
  • WebSocket.CLOSED:值为 3,表示连接已经关闭,或者打开连接失败。
 

 ③、关闭 WebSocket 链接

要关闭 WebSocket 链接,可以在任何时候调用 colse() 方法。调用了 close() 方法后,readyState 的值立即就会变成 2(正在关闭连接,而关闭连接之后就会变成 3。

 

④、发送数据

实例对象的 send() 方法用于向服务器发送数据。

 

因为 WebSocket 协议只能发送纯文本数据,所以对于复杂的数据结构,发送之前都必须通过 JSON.stringify() 方法序列化,例如

 

 ⑤、接收数据

当服务器向客户端发来消息时,WebSocket 对象就会触发 message 事件,该事件把返回的数据保存在 event.data 属性中。

 

实例对象的 message() 方法用于接收服务器返回的数据。

⑥、其他事件

实例对象还有其他三个事件,在连接生命周期的不同阶段触发。

  • open 事件:在成功建立链接时触发。
  • error 事件:在发生错误时触发,连接不能持续。
  • close 事件:在连接关闭时触发。

在这三个事件中,只有 close 事件的 event 对象有额外的信息。该事件的event对象有三个额外的属性

  • wasClean 属性:是一个布尔值,表示连接是否已经明确地关闭。
  • code 属性:服务器返回的数值状态码。
  • reason 属性:是一个字符串,包含服务器发回的消息。

可以把以上信息显示给用户,也可以记录到日志中以便将来分析。

 

进一步学习 WebSocket,请看 阮老师的 WebSocket 教程:WebSocket 教程 - 阮一峰的网络日志

关于 WebSocket 和socket 的区别请戳这里:WebSocket 和socket 的区别 - zhangniuniu - 博客园

postMessage() 方法是 HTML5 中新增的功能,用于跨文档消息传递(简称 XDM

由于我在之前的文章写过,所以恕不赘述,详情请戳:js HTML5 中定义的 Javascript 脚本_weixin79893765432...的博客-CSDN博客_js html5

实现原理: a欲与b跨域相互通信,通过中间页c来实现。 三个页面,不同域之间利用iframe的location.hash传值,相同域之间直接js访问来通信。

具体实现:A域:a.html -> B域:b.html -> A域:c.html,a与b不同域只能通过hash值单向通信,b与c也不同域也只能单向通信,但c与a同域,所以c可通过parent.parent访问a页面所有对象。

(1)、a.html:(http://www.domain1.com/a.html)

 

(2)、b.html:(http://www.domain2.com/b.html)

 

(3)、c.html:(http://www.domain1.com/c.html)

 
 

此方案仅限主域相同,子域不同的跨域应用场景。

实现原理:两个页面都通过js强制设置document.domain为基础主域,就实现了同域。

(1)、父窗口:(http://www.domain.com/a.html)

 

(2)、子窗口:(http://child.domain.com/b.html)

 
 

window.name属性的独特之处:name值在不同的页面(甚至不同域名)加载后依旧存在,并且可以支持非常长的 name 值(2MB)。

(1)、a.html:(http://www.domain1.com/a.html)

 

(2)、proxy.html:(http://www.domain1.com/proxy....
中间代理页,与a.html同域,内容为空即可。

(3)、b.html:(http://www.domain2.com/b.html)

 

总结:通过iframe的src属性由外域转向本地域,跨域数据即由iframe的window.name从外域传递到本地域。这个就巧妙地绕过了浏览器的跨域访问限制,但同时它又是安全操作。

反向代理的原理:受同源策略的限制,非同源的通信就会产生跨域,导致客户端直接与服务器通讯失败,于是另辟蹊径,可以在本地配置一个服务器(我自测采用的是Wampserver(PHP+Apache,配置好反向代理后,直接访问本地服务器,本地服务器会去访问远程服务器,服务期间的通信没有跨域,所以就绕开了跨域,借助本地服务器成功返回了数据。

反向代理学习资源大全:js的反向代理 - 腾讯云开发者社区 - 腾讯云

  • 反向代理的概念:反向代理为什么叫“反向”代理? - 腾讯云开发者社区-腾讯云
  • Node.js 配置反向代理:使用 NodeJS 实现反向代理 - 腾讯云开发者社区-腾讯云
  • Nginx 配置反向代理:Nginx的反向代理与负载均衡 - 腾讯云开发者社区-腾讯云

允许Chrome读写一个特定的文件夹。

(1)、windows 操作系统

①、打开任务管理器,确保里面没有chrome 进程 

②、右键谷歌浏览器"属性"中打开文件所在位置,进入浏览器安装文件夹

③、在文件位置栏中启动cmd命令行,输入chrome.exe,确定是否能启动浏览器。如果不能请检查自己浏览器文件的路径是否正确

④、 然后关掉chrome浏览器,通过在命令行输入chrome.exe --disable-web-security --user-data-dir 或 chrome.exe --args --disable-web-security --user-data-dir。

⑤、将指令“ --disable-web-security --user-data-dir” 或 “ --args --disable-web-security --user-data-dir”粘贴到这条下图的目标中,注意有空格,这两种方式都是一样的,直接粘贴这种其实就相当于系统打开谷歌时执行了“目标”里的指令而已。

(2)、MAC OS 操作系统

1⃣️、允许Chrome读写一个文件夹,比如:CCD。

新建一个文件夹,作为允许chrome读写的文件夹,查看其路径。

在terminal里运行以下命令

 

命令执行后,弹出窗口,提示如下图

点击启动即可开启一个新的网页,该网页已经可以读写CCD文件夹了。

2⃣️、解决302报错

再运行项目,可能会报错302(资源被重定向找不到了,怎么办呢

在浏览器地址栏输入并访问下面的网址

 

ctrl+F 搜索:same-site-by-default-cookies,并将其设置为 disabled(禁用)。

最后别忘了点击 relaunch哦。

请戳此链接:https://segmentfault.com/a/1190000011145364

首先抛出一个问题:在本地访问本机起的服务会产生跨域吗

答案是会的。下面我就来还原一下这个问题。

比如:我的 IP 地址是 192.168.x.x,我的端口号是 8080,起的服务的端口号是 8181

目标接口是http://192.168.x.x:8080/getData

我前端页面访问的 URL 是http://192.168.x.x:8080/home

所以,我做了代理(本案例用的是 vue2

 

代理后,我要访问的接口会变为http://192.168.x.x:8181/api/getData

这样做是正确的,没问题。但是,如果我前端页面访问的 URL 改为http://localhost:8080/home,会发生什么?产生跨域了。至此,问题还原了。这是为什么呢

这是因为 localhost 与 192.168.x.x 是不同的localhost 不会被 DNS 解析为本机 IP 地址,那么显然这违反了 “同源策略” 的 “同域名” 的原则了,所以就会产生跨域了。

    以上就是本篇文章【js 跨域(JSONP/CORS/WebSocket/postMessage/location.hash/document.domain/window.name)】的全部内容了,欢迎阅览 ! 文章地址:https://sicmodule.kub2b.com/news/15256.html
     栏目首页      相关文章      动态      同类文章      热门文章      网站地图      返回首页 企库往资讯移动站 https://sicmodule.kub2b.com/mobile/ , 查看更多   
最新文章
手机单扬声器和双扬声器有什么区别?原来差别这么大手机扬声器「手机单扬声器和双扬声器有什么区别?原来差别这么大」
随着手机的普及和发展,音频体验成为消费者选择手机的重要因素之一。而在手机音频方面,单扬声器和双扬声器是常见的设计方案。那
手机维修知识大全维修手机「手机维修知识大全」
修理手机维修知识大全手机是高科技精密电子产品。工作原理、制造工艺、软件和硬件、测试、技术标准在所有的电器设备中是最复杂的
2k分辨率手机有哪些(2k分辨率的手机哪款性价比最高)
  关于《2K分辨率手机有哪些》的文章  随着科技的不断发展,手机已经成为了我们日常生活中不可或缺的一部分。而在手机的各种
红手指云手机苹果版(红雀浏览器) v1.0.23 iPhone版红手指云手机「红手指云手机苹果版(红雀浏览器) v1.0.23 iPhone版」
红手指手游专用虚拟手机是一款非常实用的手机挂机软件,在这里玩家随时随地离线挂机、自动帮助你闯关升级,非常强大的游戏挂机神
1手机2(一加11手机)
  《手机2》:探索科技与生活的无限可能  在当今数字化时代,智能手机无疑是我们生活中不可或缺的一部分。随着科技的飞速发
手机NFC是什么?怎么使用?手机nfc「手机NFC是什么?怎么使用?」
但很多人不知道的是,除了这三种无线通信技术外,很多智能手机里还有一种无线通信技术,那就是NFC。2004年,飞利浦半导体,诺基
360手机 官网(360手机官网入口)
  探索《360手机官网》:一站式手机技术与服务的平台  在当今数字化时代,手机已经成为我们日常生活中不可或缺的一部分。而
关于手机电池的冷知识:机身温度过高,会永久降低手机电池容量手机电量「关于手机电池的冷知识:机身温度过高,会永久降低手机电池容量」
相信大家在日常使用手机时,最关注的就是我们手机的电量还剩多少,尤其是现在我们一般出门都不带现金,直接通过手机进行支付,所
260手机助手(360手机助手官方版下载)
  《260手机助手》:一站式手机管理和服务的新选择  随着智能手机的普及,我们的生活越来越离不开手机。为了更好地管理和优
小米发布迄今最强被动散热系统,两倍于VC散热,原神满帧运行手机散热「小米发布迄今最强被动散热系统,两倍于VC散热,原神满帧运行」
你的手机“烫”吗? 玩局游戏,瞬间化身暖手宝?拍拍视频就过热,需要“冷静”一下才能继续使用!充电是很快,温度升的也很快…