1. 什么是跨域
简单的来说就是:
在A域名下向B域名发起了 request。
一个完整的URL应该包含 http(协议)://www.baidu.com(域名):80(端口)/index.html(路由)。
同源策略 就是指的 协议,域名,端口必须保持一致。任何不符合同源策略的请求 request 都属于跨域了。
2.通过jsonp跨域
index.html页面中
Document 复制代码
server.js
let express = require('express');let app = express();app.get('/say', function(req, res){ let {wd, cb} = req.query; res.end(`${cb}('world')`); //返回 'show('world')'});复制代码
3. 通过CORS跨域
cors.html
Document hello cors.html 复制代码
- cors.html.server.js
let express = require('express');let app = express();app.use(express.static(__dirname));app.listen(3000);复制代码
- cors.target.js
let express = require('express');let app = express();let whitList = ['http://localhost:3000']; //用来访问 cors.html的页面app.use(function(req, res, next){ let origin = req.headers.origin; if(whitList.includes(origin)){ //设置允许哪个源访问我 res.setHeader('Access-Control-Allow-Origin', origin); //允许携带哪个请求头访问我 res.setHeader('Access-Control-Allow-Headers', 'name'); //允许哪个方法访问我 res.setHeader('Access-Control-Allow-Methods', 'PUT'); //允许携带cookie, 与前端 xhr.withCredentials = true; 相呼应 res.setHeader('Access-Control-Allow-Credentials', true); //允许的有效期: 第二次发送options方法的时间间隔 res.setHeader('Access-Control-Max-Age', 60); //60s //允许设置的返回头 与前端 console.log(xhr.getResponseHeader('name'));相呼应 res.setHeader('Access-Control-Expose-Headers', 'name'); if(req.method === 'OPTIONS'){ res.end(); //浏览器在发起put请求前会发送一个options方法,来验证允许访问的各种参数 } }});app.put('/getData', function(req, res){ console.log(req.headers); res.setHeader('name','jw'); res.end('hello');});app.use(express.static(__dirname));app.listen(4000)复制代码
从 http://localhost:3000 向 http://localhsot:4000 发送put 请求。
4. 通过postMessage跨域
通过 localhost:3000 访问 a.html
Document 复制代码
通过localhost:4000返回 b.html
........复制代码
5. 通过window.name 跨域
默认情况下 window.name 为 "" 有a.html, b.html, c.html. 其中a.html 和 b.html 通过http://localhost:3000访问,c.html通过 http://localhost:4000访问.
a.html
.... a和b是同域的 http://localhost:3000 c是独立的 http://localhost:4000 a获取c的数据 a先引用c c把值放到window.name, 把a引用的地址改到b
c.html
... ...复制代码
b.html
Document 复制代码
a.html 中的控制台中会打印出 hello a.html
6.通过hash方式跨域
a.html
... ...复制代码
b.html
... ...复制代码
c.html
......复制代码
7.通过domain方式跨域
a.html
... helloa ...复制代码
b.html
... hellob ...复制代码
8.通过websocket方式跨域
socket.html
...let socket = new WebSocket('ws://localhost:3000');socket.onopen = function(){ socket.send('hello');}socket.onmessage = function(e){ console.log(e.data); //打印world}...复制代码
server.js
let express = require('express');let app = express();let WebSocket = require('ws');let wss = new WebSocket.Server({port: 3000});wss.on('connection', function(ws){ console.log(data); // 打印 hello ws.send('world');});复制代码
9.通过nginx方式跨域
a.html
... ...复制代码
nginx.conf
location / { // 没有配置OPTIONS的话,浏览器如果是自动识别协议(http or https),那么浏览器的自动OPTIONS请求会返回不能跨域 if ($request_method = OPTIONS ) { add_header Access-Control-Allow-Origin "$http_origin"; add_header Access-Control-Allow-Methods "POST, GET, PUT, OPTIONS, DELETE"; add_header Access-Control-Max-Age "3600"; add_header Access-Control-Allow-Headers "Origin, X-Requested-With, Content-Type, Accept, Authorization"; add_header Access-Control-Allow-Credentials "true"; add_header Content-Length 0; add_header Content-Type text/plain; return 200; } add_header 'Access-Control-Allow-Origin' '$http_origin'; add_header 'Access-Control-Allow-Credentials' 'true'; add_header 'Access-Control-Allow-Methods' 'GET, PUT, POST, DELETE, OPTIONS'; add_header 'Access-Control-Allow-Headers' 'Content-Type,*'; proxy_pass http://127.0.0.1:8080; }}复制代码
nginx的方式有些类似cors。
10.小结
平时工作中可能熟知cors 和 jsonp, 这里大概将其原理实现了。以后再遇到面试官问你。就可以淡定的告诉他。然后还可以介绍其他的几种方式。用跨域的方式震慑住他。哈哈哈~~