跨域是一个咱们常常遇到的问题,特别是当服务有两个域名的时候,若是你的页面是在
a.test.com
,而后须要向b.test.com
请求数据,这个时候就存在跨域的问题了。若是你直接请求,你就会发现浏览器就直接报错了,这个时候就要了解什么是 同源策略 了。javascript
同源策略限制从一个源加载的文档或脚本如何与来自另外一个源的资源进行交互,这是一个用于隔离潜在恶意文件的关键安全机制。css
协议、域名与端口。这三者任何一个不同的话,就算是不一样源,就会产生跨域的问题。html
不是一个源的文档,就没有权限去操做另外一个源的文档。前端
Cookie、LocalStorage 和 IndexDB没法读取。java
Dom没法得到node
Ajax请求不能发送jquery
举个简单的例子,咱们登录是须要带上 cookie
的,好比咱们登陆了一个银行网站,那么咱们的浏览器中则会带上相应的 cookie
,下次咱们这个银行网站的时候,若是这个 cookie
还存在的话,就能够不须要登陆了;webpack
若是浏览器没有同源策略,那么一些不法分子能够拿到咱们浏览器的 cookie
从而进咱们的银行帐号取钱,这是很是可怕的事情。nginx
这就是浏览器要有同源策略的缘由。git
URL 说明 是否容许通讯
http://www.domain.com/a.js
http://www.domain.com/b.js 同一域名,不一样文件或路径 容许
http://www.domain.com/lab/c.js
http://www.domain.com:8000/a.js
http://www.domain.com/b.js 同一域名,不一样端口 不容许
http://www.domain.com/a.js
https://www.domain.com/b.js 同一域名,不一样协议 不容许
http://www.domain.com/a.js
http://192.168.4.12/b.js 域名和域名对应相同ip 不容许
http://www.domain.com/a.js
http://x.domain.com/b.js 主域相同,子域不一样 不容许
http://domain.com/c.js
http://www.domain1.com/a.js
http://www.domain2.com/b.js 不一样域名 不容许
复制代码
由于浏览器存在跨域这个问题,可是咱们平时在开发过程当中,有不少场景须要用到跨域通讯,好比前端和后端的接口源不是同一个的时候,这个时候咱们就须要进行跨域通讯了。
jsonp
CORS
:跨域资源共享postMessage
:HTML5
提供的 api
Hash
:不一样源能够访问 hash
window.name
:不一样的页面(甚至不一样域名)加载后依旧存在document.domain
:主域相同的状况websocket
:HTML5
提供的新的协议webpack
:等构建构建工具中提供的跨域解决办法nginx
:这个属于后端的,笔者在本文就不作详细介绍了,你们能够自行找相关资料,其实也蛮简单的接下来咱们来详细讲一下这几种解决跨域问题的通讯方式,全部代码都会放在这个仓库中:跨域通讯 示例代码。
一般为了减轻 web
服务器的负载,咱们把 js
、css
,img
等静态资源分离到另外一台独立域名的服务器上,在html
页面中再经过相应的标签从不一样域名下加载静态资源,而被浏览器容许。
基于此原理,咱们能够经过动态建立 script
,再请求一个带参网址实现跨域通讯。
咱们新建 jsonp
文件夹,并新建三个文件
jsonp
方法,jsonp
其实就是新建一个 script
文件,由于咱们上面也讲到了 script
是不会跨域的,接着将须要请求的连接放在 script
的 src
中,同时在 window
上挂一个全局 callback
方法,后端返回的时候会将你要的数据放在这个 callback
的参数中,这个时候你就能够获得这些数据了。function jsonp ({ url, params, cb }) {
return new Promise(function(resolve, reject) {
let script = document.createElement('script');
// 全局挂一个方法
window[cb] = function(data) {
resolve(data);
document.body.removeChild(script);
}
// 将 cb 放在 params 中
params = { ...params, cb};
let arrs = [];
// 将 params 中的 key 拼成相似 a=1 形式
for(let key in params) {
arrs.push(`${key}=${params[key]}`);
}
// 开始拼 url,目标结果 a=1&b=2&c=3
script.src = `${url}?${arrs.join('&')}`;
document.body.appendChild(script);
})
}
复制代码
express
来起一个 Node.js
服务,接下去其余项目的例子笔者也会使用相似于下面这个 js
来启动服务,若是是增长方法我会特别标出:let express = require('express');
let app = express();
// 以当前目录做为服务器静态目录
// 咱们能够经过 localhost:3000/index.html 访问 html 文件
app.use(express.static(__dirname));
app.get('/jsonp', function(req, res) {
// 准备放回给前端的数据
const data = {
data: '我是 jsonp 的 data',
}
// 获取前端传的 cb 方法
const { cb } = req.query;
// 设置输出的 html 格式为 utf-8
res.writeHead(200,{'Content-Type':'text/html;charset=utf-8'})
if (cb) {
// 若是有 cb 参数,就讲 data 返回给前端
res.end(`${cb}(${JSON.stringify(data)})`);
} else {
// 若是没有 cb,就返回错误
res.end('未传 callback 参数');
}
})
app.listen(3000, () => {
console.log('服务器已经在3000端口启动');
});
复制代码
jsonp
例子 html
文件,发 jsonp
的请求...
<body>
<h1>Jsonp 的 demo</h1>
<script src="./jsonp.js"></script>
<script> jsonp({ url: 'http://localhost:3000/jsonp', params: { key: '1', }, cb: 'showData', }).then((data) => { console.log('data', data); }) </script>
</body>
...
复制代码
咱们在根目录下运行一下 node ./jsonp/server.js
,访问 localhost:3000
:
能够看到在页面中显示了 index.html
的内容,同时在控制台输出了相应的 data
:
在 jquery
中已经帮咱们封装好了,直接使用便可,但须要先引入 jquery
,可使用 $.ajax
规定 dataType
,具体笔者也不演示了,使用以下:
// ...
$.ajax({
url: 'http://localhost:3000/jsonp',
type: 'get',
dataType: 'jsonp', // 请求方式为jsonp
success:function(ret){
console.log(ret);
}
});
复制代码
使用起来很简单,兼容性好,能兼容一些远古浏览器。可是他只支持 GET
请求,同时会有安全的问题,可能会被 xss
注入。
CORS
是一个 W3C
标准,全称是"跨域资源共享"(Cross-origin resource sharing
)。它容许浏览器向跨源发送 XMLHttpRequest
,主要在后端服务器中增长一些相关配置便可,但有的时候须要前端进行一些配合,接下来我会讲几个经常使用的配置:
咱们新建 cors
文件夹,并新建四个文件,一个 html
文件,两个服务器文件,一个本身的服务器文件,一个目标服务器文件,用来咱们作请求使用;一个简单封装的 ajax.js
文件:
这里写了一个简单的 ajax
,具体就不细讲了,你们想深刻研究能够参考:Ajax 知识体系大梳理。
function ajax( methods, url ) {
// 新建一个 xhr 实例
// 在这里没有兼容 IE6, IE5,
// IE6,IE5 可使用 newActiveXObject("Microsoft.XMLHTTP");
const xhr = new XMLHttpRequest();
// 初始化一个请求
// methods:请求类型
// url:连接
// async:是否异步,true (异步); false(同步)
xhr.open(methods, url, true);
// 只要 readyState 属性发生变化
// 状态变化的监听函数
xhr.onreadystatechange = function() {
if (xhr.readyState === 4) {
// 返回成功的时候,输出相应的 response
if (xhr.status >= 200 && xhr.status < 300 || xhr.status === 304) {
console.log(xhr.response);
}
}
}
xhr.send();
}
复制代码
server
文件这个文件和 jsonp
的 server.js
同样,在 3000
端口开启一个服务器,让咱们的 index.html
可以在 localhost:3000/index.html
访问。
这个文件是目标服务器文件,端口号 4000
,用来咱们发送 ajax
请求,这里咱们增长了一个 getData
方法:
// ...
app.get('/getData', function(req, res) {
const data = {
data: '我是 cors 的 data',
}
res.end(JSON.stringify(data));
})
// ...
复制代码
html
文件用来发送 ajax
请求:
...
<body>
<h1>Cors demo</h1>
<script src="./ajax.js"></script>
<script> ajax('GET', 'http://localhost:4000/getData'); </script>
</body>
...
复制代码
接下来咱们启动两个服务,访问一下 localhost:3000/index.html
发现有一个报错:
这时咱们就须要在后端配置 CORS
了。
咱们能够修改一下 server2.js
,增长 Access-Control-Allow-Origin
这个头,通常来讲咱们改为 *
,就能解决这个问题了,可是在项目中,咱们可能须要设置一个白名单,规定哪些源能够访问,咱们能够作以下配置:
let whiteList = ['http://localhost:3000']
// exprss 的一个中间件,全部的路由都会走一下
app.all('*', function (req, res, next) {
// 获取请求的源
let origin = req.headers.origin;
if (whiteList.includes(origin)) {
// 设置哪一个源访问
res.setHeader('Access-Control-Allow-Origin', origin);
} else {
// 不在白名单中 返回
res.end('你不在白名单中');
}
// 继续执行
next();
});
复制代码
这个时候咱们从新运行 server2.js
,咱们就能拿到相应的值了:
咱们再来介绍几个经常使用的配置:
若是用户想要在头部设置一些值,则在后端须要定义这个头,它也是一个逗号分隔的字符串,代表服务器支持的全部头信息字段。若是不定义会报以下错误:
若是咱们想要在 header
中增长 name=darrell
,咱们在 ajax.js
中新增以下代码:
//...
xhr.open(methods, url, true);
// ...
xhr.setRequestHeader('name', 'darrell'); // 增长一个头
// ...
xhr.send();
复制代码
在 servers.js
增长:
// ...
app.all('*', function (req, res, next) {
// ...
if (whiteList.includes(origin)) {
// 设置哪一个源访问
res.setHeader('Access-Control-Allow-Origin', origin);
// 容许前端携带哪一个头访问我
res.setHeader('Access-Control-Allow-Headers', 'name,key');
}
// ...
});
复制代码
它的值是逗号分隔的一个字符串,代表服务器支持的全部跨域请求的方法。若是个人请求方法为 put
,不设置次字段会报错:
在 server.js
中增长此头:
app.all('*', function (req, res, next) {
// ...
if (whiteList.includes(origin)) {
// 设置哪一个源访问
res.setHeader('Access-Control-Allow-Origin', origin);
// 容许前端携带哪一个头访问我
res.setHeader('Access-Control-Allow-Headers', 'name,key');
// 容许哪一个方法访问
res.header("Access-Control-Allow-Methods","PUT");
}
// ...
});
复制代码
它的值是一个布尔值,表示是否容许发送 Cookie
。默认状况下,Cookie
不包括在 CORS
请求之中。设为 true
,即表示服务器明确许可,Cookie
能够包含在请求中,一块儿发给服务器。
若是在浏览器端设置了容许携带 cookie
:xhr.withCredentials = true;
,那么必需要在后端设置这个头,否则会以下错:
在 server.js
中增长此头:
app.all('*', function (req, res, next) {
// ...
if (whiteList.includes(origin)) {
// 设置哪一个源访问
res.setHeader('Access-Control-Allow-Origin', origin);
// 容许前端携带哪一个头访问我
res.setHeader('Access-Control-Allow-Headers', 'name,key');
// 容许哪一个方法访问
res.header("Access-Control-Allow-Methods","PUT");
// 容许携带 cookie
res.header("Access-Control-Allow-Credentials", true);
}
// ...
});
复制代码
CORS
请求时,XMLHttpRequest
对象的 getResponseHeader()
方法只能拿到6个基本字段:Cache-Control
、Content-Language
、Content-Type
、Expires
、Last-Modified
、Pragma
。若是想拿到其余字段,就必须在 Access-Control-Expose-Headers
里面指定。
好比我要在 ajax
的 response
中取返回头中的 name
:
// ...
if (xhr.readyState === 4) {
if (xhr.status >= 200 && xhr.status < 300 || xhr.status === 304) {
console.log(xhr.response);
console.log(xhr.getResponseHeader('name'));
}
}
// ...
复制代码
同时在 getData
这个接口写一个 name
上去:
app.get('/getData', function(req, res) {
// ...
res.setHeader('name', 'maolei');
// ...
})
复制代码
若是后端没有设置次头,则会有以下报错:
在 server.js
中增长此头:
app.all('*', function (req, res, next) {
// ...
if (whiteList.includes(origin)) {
// 设置哪一个源访问
res.setHeader('Access-Control-Allow-Origin', origin);
// 容许前端携带哪一个头访问我
res.setHeader('Access-Control-Allow-Headers', 'name,key');
// 容许哪一个方法访问
res.header("Access-Control-Allow-Methods","PUT");
// 容许携带 cookie
res.header("Access-Control-Allow-Credentials", true);
// 容许前端获取哪一个头
res.header("Access-Control-Expose-Headers", 'name');
}
// ...
});
复制代码
用来指定本次预检请求的有效期,单位为秒。预检请求指的是浏览器针对于复杂请求的时候,会在正式通讯以前,增长一次HTTP查询请求(option
),称为 预检请求。咱们能够设置这个请求的有效期:
app.all('*', function (req, res, next) {
// ...
if (whiteList.includes(origin)) {
// 设置哪一个源访问
res.setHeader('Access-Control-Allow-Origin', origin);
// 容许前端携带哪一个头访问我
res.setHeader('Access-Control-Allow-Headers', 'name,key');
// 容许哪一个方法访问
res.header("Access-Control-Allow-Methods","PUT");
// 容许携带 cookie
res.header("Access-Control-Allow-Credentials", true);
// 容许前端获取哪一个头
res.header("Access-Control-Expose-Headers", 'name');
// 用来指定本次预检请求的有效期,单位为秒
res.header("Access-Control-Max-Age","6");
}
// ...
});
复制代码
更多的请求,笔者在这里就不讲了,你们能够参考阮一峰老师的 跨域资源共享 CORS 详解
CORS
请求是比较安全的,并且支持全部类型的 HTTP
请求,配置起来也相对比较方便;开发者可使用普通的 XMLHttpRequest
发起请求和得到数据,比起 JSONP
有更好的错误处理;并且在绝大多数现代浏览器都已经支持了 CORS
,若是业务中不须要兼容远古浏览器的,就能够放心的使用 CORS
了。
postMessage
是 HTML5
中的API,且是为数很少能够跨域操做的 window
属性之一,它可用于解决如下方面的问题
opener
来进行通行。iframe
消息传递这里咱们就来举一个 iframe
嵌套的例子:
咱们新建 postmessage
文件夹,并新建四个文件,两个不一样源 html
文件,两个服务器文件,一个本身的服务器文件,一个目标服务器文件,用来咱们作请求使用;
在 a.html
中新建一个 iframe
,其 src
为 http://localhost:4000/b.html
:
<!-- a.html -->
...
<body>
<h1>postmessage A 页面</h1>
<iframe src="http://localhost:4000/b.html" id="frame" frameborder="10" onload="load()" ></iframe>
</body>
...
<!-- b.html -->
...
<body>
<h1>postmessage B 页面</h1>
</body>
...
复制代码
两个 server
文件和 CORS
同样,只不过都是开启两个简单的服务而已。
我么想要从 a
页面发送一些信息给 b
页面,同时 b
在收到消息后在回信给 a
页面。
咱们能够修改 a.html
,补充 iframe
的 load
函数,咱们在 a
页面发送咱们定义好的信息给 b
页面,同时监听 b
页面回发过来的信息,具体配置可参考 postMessge
官方文档:
...
<script> function load() { let frame = document.getElementById("frame"); var iwindow = frame.contentWindow; // 发送 postMessage 信息 // 第一个:要传的数据 // 第二个:指定源 iwindow.postMessage({ type: 'a', data: "我是 a 发的消息", }, "http://localhost:4000") } // 监听 b 页面发过来的信息 window.addEventListener('message', function(event){ // 拿到数据,判断是否是从 b 发过来的 // 若是不是 直接 return const { type, data } = event.data; if (!event.data || type !== 'b') { return; } console.log(data); }) </script>
...
复制代码
在 b
中监听 a
发过来的信息:
...
<script> window.addEventListener('message', function(event){ console.log(event.data.data); event.source.postMessage({ type: 'b', data: "我是 b 发的消息", }, event.origin); }) </script>
...
复制代码
咱们开启两个服务,在页面中打开 localhost:3000/a.html
,能够看到信息打印了出来:
不一样域之间能够经过 window.location.hash
进行传递相应的信息,在同域名直接能够直接经过 js
访问来设置:
咱们新建 hash
文件夹,并新建五个文件,三个 html
文件,两个同源 html
,一个不一样源 html
,两个服务器文件,一个本身的服务器文件,一个目标服务器文件,用来咱们作请求使用,服务器文件和以前同样,就不列举了。
两个同源 html
:a
和 b
文件,在 3000
端口下,另一个 c
在 4000
端口下:
<!-- a.html -->
...
<body>
<!-- 路径后的 hash 能够用来通讯 -->
<!-- a 访问 c -->
<h1>window-hash a.html</h1>
<iframe src="http://localhost:4000/c.html#hashname=darrell" id="frame" frameborder="10" ></iframe>
</body>
...
<!-- b.html -->
...
<body>
<h1>window-hash b.html</h1>
</body>
...
<!-- c.html -->
...
<body>
<h1>window-hash c.html</h1>
</body>
...
复制代码
完成 a
与 c
页面的通讯过程,在 a.html
中的 iframe
向 c.html
发送 #hashname=darrell
,c
取到以后在发送相关的信息给 a
,a
在进行相应的处理。
其实很简单,咱们在 c
获得 a
发过来的信息以后在新建 iframe
指向一个和a
同源的 b
,做为一个中转站,由于 a
和 b
同源,接着就能够直接经过 js
访问了,咱们修改一下 html
代码:
<!-- a.html -->
...
<body>
<!-- 路径后的 hash 能够用来通讯 -->
<!-- a 访问 c -->
<h1>window-hash a.html</h1>
<iframe src="http://localhost:4000/c.html#hashname=darrell" id="frame" frameborder="10" ></iframe>
<script> // 监听 b 修改 hashchange window.onhashchange = function() { console.log('a 收到', location.hash); } </script>
</body>
...
<!-- b.html -->
...
<body>
<h1>window-hash b.html</h1>
<script> // 收到 c 发过来的 hash console.log('b 收到', location.hash); window.parent.parent.location.hash = window.location.hash; </script>
</body>
...
<!-- c.html -->
...
<body>
<h1>window-hash c.html</h1>
<script> // 收到 a 发过来的 hash console.log('c 收到', window.location.hash); let iframe = document.createElement('iframe'); iframe.src = 'http://localhost:3000/b.html#name=c'; document.body.appendChild(iframe); </script>
</body>
...
复制代码
咱们开启两个服务,在页面中打开 localhost:3000/a.html
,能够看到信息打印了出来:
window.name
有一个特性,就是 name
值在不一样的页面(甚至不一样域名)加载后依旧存在。所以咱们也可使用其帮助咱们解决跨域问题。
咱们新建 name
文件夹,并新建五个文件,代码和 hash
的文件代码同样。
<!-- a.html -->
...
<body>
<h1>window-name a.html</h1>
<iframe src="http://localhost:4000/c.html#hashname=darrell" id="frame" frameborder="10" ></iframe>
</body>
...
<!-- b.html -->
...
<body>
<h1>window-name b.html</h1>
</body>
...
<!-- c.html -->
...
<body>
<h1>window-name c.html</h1>
<script> window.name = '我是来自 c 的信息'; </script>
</body>
...
复制代码
需求也相似,我须要在 a
获取到 c
这个页面进行定义的 window.name
,其实很简单咱们只要经过 b
这个中间页面进行数据传递就好了,当咱们加载完成 c
页面这个 iframe
之后,再从新将 src
赋值为 http://localhost:3000/b.html
,利用 name
的特性,这个时候 a
页面就能够经过 window.name
拿到 c
中的 name
了,咱们只须要修改 a.html
文件就能够了:
<!-- a.html -->
...
<body>
<h1>window-name a.html</h1>
<iframe src="http://localhost:4000/c.html" id="frame" frameborder="10" onload="load()" ></iframe>
<script> let first = true; function load() { let frame = document.getElementById("frame"); let iwindow = frame.contentWindow; if (first) { frame.src = 'http://localhost:3000/b.html'; first = false; } else { console.log(iwindow.name); } } </script>
</body>
...
复制代码
咱们开启两个服务,在页面中打开 localhost:3000/a.html
,能够看到信息打印了出来:
在两个域名是同一个主域的时候,若是须要进行跨域通讯,咱们能够将两个页面都经过 js
强制设置document.domain
为基础主域,这就实现了同域。
咱们新建 domain
文件夹,并新建四个文件,两个不一样源的 html
,两个服务文件和 name
相同:
咱们配置一下系统的 host
文件,将 127.0.0.1
配置出两个虚拟域名:a.example.cn
、b.example.cn
:
这样咱们就能使用 a.example.cn:3000/a.html
和 b.example.cn:4000/b.html
来访问两个 html
文件了,
由于两个域名的主域相同,咱们能够设置 document-domain=example.cn
来实现:
<!--a.html-->
...
<body>
<!-- 配置 host -->
<!-- http://a.example.cn:3000/a.html -->
<h1>document-domain a.html</h1>
<iframe src="http://b.example.cn:3000/b.html" id="frame" frameborder="10" onload="load()" ></iframe>
<script> document.domain = "example.cn"; function load() { let frame = document.getElementById("frame"); let iwindow = frame.contentWindow; console.log(iwindow.name); } </script>
</body>
...
<!--b.html-->
...
<body>
<h1>document-domain b.html</h1>
<script> document.domain = "example.cn"; var name = 'b 定义的 name'; </script>
</body>
...
复制代码
咱们开启两个服务,在页面中打开 http://a.example.cn/:3000/a.html
,能够看到信息打印了出来:
须要注意的是此方案只能在主域相同,子域不一样的跨域应用场景。其余状况下不能使用。
WebSocket
是 HTML5
一种新的协议。它实现了浏览器与服务器全双工通讯,同时容许跨域通信。
咱们先用原生的 WebSocket
来举个例子,以后再使用 Socket.io
来举个例子:
WebSocket
咱们新建 websocket
文件夹,新建 socket.html
和 server.js
文件:
咱们建立一个 socket
实例,并向服务端发送一些消息,同时监听服务端发送给客户端的消息。
...
<body>
<h1>Socket demo</h1>
<script> let socket = new WebSocket("ws://localhost:3000"); socket.onopen = function() { socket.send('浏览器发出的内容'); } socket.onmessage = function(e) { console.log(e.data); } </script>
</body>
...
复制代码
咱们安装一个依赖 ws
,用来处理 websocket
,接着起一个 websocket
服务器,监听客户端的信息,同时发送相应的信息出到客户端。
let express = require('express');
let WebSocket = require('ws');
let wss = new WebSocket.Server({ port: 3000 });
wss.on('connection', function(ws) {
ws.on('message', function(data) {
console.log(data);
ws.send('服务器发的内容');
})
})
复制代码
咱们开启一下服务,这个时候咱们能够直接打开 file
协议的 socket.html
,咱们能够在控制台看到服务器发送过来的信息,同时也能够在服务端开到客户端发送过来的信息:
由于原生 WebSocket API
不是特别好用,兼容性也很差,咱们可使用 Socket.io
,它很好地封装了 webSocket
接口,提供了更简单、灵活的接口。同时对不支持 Websocket
的浏览器作了向下兼容。
咱们这个例子参考了官方的一个 简易聊天室,同时咱们须要安装一下 socket.io
:
npm install socket.io
复制代码
<!-- 引入 socketIO.html -->
...
<body>
<ul id="messages"></ul>
<form action="">
<input id="m" autocomplete="off" /><button>Send</button>
</form>
</ul>
<!-- 引入 socket.io 和 jquery 的 cdn -->
<script src="https://cdn.bootcss.com/socket.io/2.2.0/socket.io.js"></script>
<script src="https://code.jquery.com/jquery-1.11.1.js"></script>
<script> $(function () { //创建一个socket var socket = io(); $('form').submit(function(){ //发送socket到服务器。 socket.emit('chat message', $('#m').val()); $('#m').val(''); return false; }); socket.on('chat message', function(msg){ //接受服务器传回来的数据,新建一个li标签 $('#messages').append($('<li>').text(msg)); window.scrollTo(0, document.body.scrollHeight); }); }); </script>
</body>
...
复制代码
var app = require('express')();
var http = require('http').createServer(app);
var io = require('socket.io')(http);
var port = process.env.PORT || 3000;
app.get('/', function(req, res){
res.sendFile(__dirname + '/socketIO.html');
});
io.on('connection', function(socket){
// 监听socket是否链接,若是链接的话,就发送数据,chat-message
socket.on('chat message', function(msg){
io.emit('chat message', msg);
});
// 监听socket是否断开,断开时执行相应的方法
socket.on('disconnect', function(){
console.log('user disconnected');
});
});
http.listen(port, function(){
console.log('listening on *:' + port);
});
复制代码
咱们启动一下服务:node ./websocket/serverIO.js
:咱们能够在两个页面互发消息,以下图:
若是你在你的项目中使用了 webpack
,那么 webpack
的 devServer
中提供了相应的配置参数,你只要在其中进行配置便可:
module.exports = {
...
devServer: {
// 代理
proxy: {
'/movie/': {
target: 'https://douban.uieee.com/v2',
// 是否能够容许跨域
changeOrigin: true,
headers: {
host:'www.example.org',
cookie: 'isLogin=1' // 判断是否登陆的 cookie 信息
}
}
}
}
};
复制代码
更多的关于 webpack
中 devServer
的配置,你们能够参考笔者写的 webpack-dev-server 高级配置,在这里就不细讲了。
文章参考了 前端常见跨域解决方案(全),同时加入了本身的思考和代码示例,但愿你们看完以后,能对跨域通讯的解决办法了然于胸。