跨域 跨域的产生 浏览器同源策略 同源策略是浏览器最基本的最核心的安全功能,A
网页的 cookie
B 网页不能使用,除非这两个网页同源。同源即"协议 + 域名 + 端口"三者相同(两个不同的域名指向同一个 ip 地址也非同源)
在进行异步网络请求的时候,如果请求的地址与当前地址的域名(ip) 、 协议 、 端口 中有任何一个不同就会产生跨域。
解决跨域方案 JSONP (JSON with Padding) 原理:利用 <script>
的 src 属性,动态添加<script>
标签,每次请求的返回内容都是由后端生成的一段 JS 代码。这段代码会通过<script>
加载,然后交给到 JS 引擎去执行,一般的里面会调用一个已经存在的函数,这个函数名是由客户端的这次请求带给服务器的。
利用浏览器允许 <script>
下载不同网站的 JS 脚本 通过手动创建一个 script 标签 相当于在客户端提供一个接口供服务器调用。不过一般服务器对客户端是 1 对多的模式,所以通常由客户端将本地提供的接口(函数)通过传递参数的形式传递给服务器。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 //index.html <!DOCTYPE html > <html lang ="en" > <head > <meta charset ="UTF-8" > <meta name ="viewport" content ="width=device-width, initial-scale=1.0" > <title > Document</title > </head > <body > <script src ="./demo.js" > </script > </body > </html >
1 2 3 4 5 6 7 8 9 10 11 12 13 14 var script = document .createElement ('script' )script.src = 'http://127.0.0.1:8880?callback=sayHello' document .head .appendChild (script)function sayHello (msg ) { console .log (msg) } function demo ( ) { console .log ('这是前台的函数' ) }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 var qs = require ('querystring' )var http = require ('http' );var server = http.createServer (function (req, res ) { var params = qs.parse (req.url .split ('?' )[1 ]); var fn = params.callback ; const msg = '后台已经收到' const ret = fn + '("' + msg + '")' ; fn && res.write (ret) res.write (';demo()' ) res.write (';document.title="通过后台修改前台的网页标题"' ) res.end (); }); server.listen (8880 , function ( ) { console .log ('Server is running at port 8880...' ); });
缺点 只能实现 get
一种请求 前端的数据可能遭受到服务器的恶意修改(上面的后台修改掉前台的网站标题)虽然我们信任服务器,但对前后台分离开发模式下,我前端不想被你后台横插一脚。 document.domain + iframe 只适用于顶级域名相同的情况 例: demo1.example.com 想获取 demo2.example.com 的数据 1. 在 demo1.example.com 下设置当前的 domain document.domain = 'xxx'
2. 在 demo1.example.com 下通过 iframe 加载 demo2.example.com 3. 修改 demo2.example.com 的 domain 和 setp 1 的 domain 一致。 4. 这个时候就可以在 demo1.example.com 下通过 iframe 获取 demo2.example.com 的 window 对象 location.hash + iframe 跨域 和 document.domain + iframe 类似 使用 window.onhashchange 进行双向交流,父窗口可以对 iframe 的 url 进行读写,iframe 也可以对父窗口的 url 进行读写 跨域资源共享(CORS) 服务器设置 Access-Control-Allow-Origin 也是常用的方法 Nginx 反向代理 通过 Nginx 设置反向代理访问我们需要请求的资源 跨域受浏览器(同源策略)影响,但服务器上的 Nginx 是不受跨域限制(没有浏览器的同源策略) 通过 Nginx 设置代理,当 A 访问 B 跨域时,我们可以设置一个 Nginx(C)帮我们转发请求,就变成了 A->C->B postMessage + iframe onload postMessage 允许用户在两个窗口或 iframe 之间传递数据,无论这个 window 对象是不是同源都能发送。