前端常见跨域解决方案

前端嗤之以鼻跨域施工方案(全)

2017/09/14 · 底蕴本事 · 3 评论 · 跨域

初藳出处: 安静de沉淀   

何以是跨域?

哪些是跨域?

跨域是指贰个域下的文书档案或脚本策画去央求另叁个域下的财富,这里跨域是广义的。

广义的跨域:

1.卡塔尔国 财富跳转: A链接、重定向、表单提交 2.卡塔尔(قطر‎能源嵌入:<link>、<script>、<img>、<frame>等dom标签,还应该有样式中background:url(卡塔尔国、@font-face(卡塔尔(英语:State of Qatar)等文件外链 3.卡塔尔 脚本乞求: js发起的ajax央求、dom和js对象的跨域操作等

1
2
3
1.) 资源跳转: A链接、重定向、表单提交
2.) 资源嵌入:<link>、<script>、<img>、<frame>等dom标签,还有样式中background:url()、@font-face()等文件外链
3.) 脚本请求: js发起的ajax请求、dom和js对象的跨域操作等

实际大家经常所说的跨域是狭义的,是由浏览器同源计谋节制的大器晚成类乞请场景。

什么样是同源攻略?
同源计策/SOP(萨姆e origin policy)是生机勃勃种约定,由Netscape公司1995年引进浏览器,它是浏览器最基本也最基本的拉萨作用,倘若缺点和失误了同源战术,浏览器超级轻松受到XSS、CSF宝马X5等攻击。所谓同源是指”公约 域名 端口”三者生龙活虎致,尽管五个分歧的域名指向同三个ip地址,也非同源。

同源攻略限定之下三种表现:

1.卡塔尔国 Cookie、LocalStorage 和 IndexDB 不能够读取 2.卡塔尔(قطر‎ DOM 和 Js对象不可能获得3.卡塔尔国 AJAX 央浼不能够发送

1
2
3
1.) Cookie、LocalStorage 和 IndexDB 无法读取
2.) DOM 和 Js对象无法获得
3.) AJAX 请求不能发送

 

遍布跨域场景

USportageL 表明 是还是不是同意通讯 同风度翩翩域名,不相同文件或路线 允许 同生龙活虎域名,不相同端口 分裂意 同风流倜傥域名,不相同协商 区别意 域名和域名对应形似ip 不相同意 主域相符,子域分裂不容许 差异域名 不容许

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
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        不同域名                         不允许

跨域是指三个域下的文书档案或脚本筹算去乞求另贰个域下的财富,这里跨域是广义的。

跨域实施方案

1、 通过jsonp跨域
2、 document.domain iframe跨域
3、 location.hash iframe
4、 window.name iframe跨域
5、 postMessage跨域
6、 跨域能源分享(CO智跑S)
7、 nginx代理跨域
8、 nodejs中间件代理跨域
9、 WebSocket商业事务跨域

 

一、 通过jsonp跨域

日常为了减轻web服务器的负载,我们把js、css,img等静态能源分离到另少年老成台独立域名的服务器上,在html页面中再经过相应的标签从不一致域名下加载静态财富,而被浏览器允许,基于此原理,我们可以透过动态成立script,再央求七个带参网站达成跨域通讯。

1.)原生完成:

<script> var script = document.createElement('script'卡塔尔(قطر‎; script.type = 'text/javascript'; // 传参并钦命回调实施函数为onBack script.src = ''; document.head.appendChild(script卡塔尔(قطر‎; // 回调施行函数 function onBack(res卡塔尔{ alert(JSON.stringify(res卡塔尔(قطر‎卡塔尔国; } </script>

1
2
3
4
5
6
7
8
9
10
11
12
13
<script>
    var script = document.createElement('script');
    script.type = 'text/javascript';
 
    // 传参并指定回调执行函数为onBack
    script.src = 'http://www.domain2.com:8080/login?user=admin&callback=onBack';
    document.head.appendChild(script);
 
    // 回调执行函数
    function onBack(res) {
        alert(JSON.stringify(res));
    }
</script>

服务端重返如下(重临时即进行全局函数):

onBack({"status": true, "user": "admin"})

1
onBack({"status": true, "user": "admin"})

2.)jquery ajax:

$.ajax({ url: '', type: 'get', dataType: 'jsonp', // 央浼情势为jsonp jsonpCallback: "onBack", // 自定义回调函数名 data: {} }卡塔尔(قطر‎;

1
2
3
4
5
6
7
$.ajax({
    url: 'http://www.domain2.com:8080/login',
    type: 'get',
    dataType: 'jsonp',  // 请求方式为jsonp
    jsonpCallback: "onBack",    // 自定义回调函数名
    data: {}
});

3.)vue.js:

this.$http.jsonp('', { params: {}, jsonp: 'onBack' }).then((res) => { console.log(res); })

1
2
3
4
5
6
this.$http.jsonp('http://www.domain2.com:8080/login', {
    params: {},
    jsonp: 'onBack'
}).then((res) => {
    console.log(res);
})

后端node.js代码示例:

var querystring = require('querystring'); var http = require('http'); var server = http.createServer(); server.on('request', function(req, res) { var params = qs.parse(req.url.split('?')[1]卡塔尔国; var fn = params.callback; // jsonp重返设置 res.writeHead(200, { 'Content-Type': 'text/javascript' }卡塔尔; res.write(fn '(' JSON.stringify(params卡塔尔国 '卡塔尔(قطر‎'卡塔尔; res.end(卡塔尔; }卡塔尔; server.listen('8080'卡塔尔国; console.log('Server is running at port 8080...'卡塔尔国;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
var querystring = require('querystring');
var http = require('http');
var server = http.createServer();
 
server.on('request', function(req, res) {
    var params = qs.parse(req.url.split('?')[1]);
    var fn = params.callback;
 
    // jsonp返回设置
    res.writeHead(200, { 'Content-Type': 'text/javascript' });
    res.write(fn '(' JSON.stringify(params) ')');
 
    res.end();
});
 
server.listen('8080');
console.log('Server is running at port 8080...');

jsonp劣点:只好促成get风流罗曼蒂克种央求。

广义的跨域:

二、 document.domain iframe跨域

此方案仅限主域相像,子域分化的跨域应用途景。

落到实处原理:七个页面都因此js强制设置document.domain为根底主域,就完结了同域。

1.)父窗口:(

<iframe id="iframe" src="; <script> document.domain = 'domain.com'; var user = 'admin'; </script>

1
2
3
4
5
<iframe id="iframe" src="http://child.domain.com/b.html"></iframe>
<script>
    document.domain = 'domain.com';
    var user = 'admin';
</script>

2.)子窗口:(

<script> document.domain = 'domain.com'; // 获取父窗口中变量 alert('get js data from parent ---> ' window.parent.user卡塔尔(قطر‎; </script>

1
2
3
4
5
<script>
    document.domain = 'domain.com';
    // 获取父窗口中变量
    alert('get js data from parent ---> ' window.parent.user);
</script>

 

三、 location.hash iframe跨域

福如东海原理: 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:(

<iframe id="iframe" src="" style="display:none;"></iframe> <script>     var iframe = document.getElementById('iframe');     // 向b.html传hash值     setTimeout(function() {         iframe.src = iframe.src '#user=admin';     }, 1000卡塔尔国;          // 开放给同域c.html的回调方法     function onCallback(res卡塔尔(قطر‎ {         alert('data from c.html ---> ' res卡塔尔(قطر‎;     } </script>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<iframe id="iframe" src="http://www.domain2.com/b.html" style="display:none;"></iframe&gt
<script>
    var iframe = document.getElementById('iframe');
 
    // 向b.html传hash值
    setTimeout(function() {
        iframe.src = iframe.src '#user=admin';
    }, 1000);
    
    // 开放给同域c.html的回调方法
    function onCallback(res) {
        alert('data from c.html ---> ' res);
    }
</script>

2.)b.html:(

<iframe id="iframe" src="" style="display:none;"></iframe> <script>     var iframe = document.getElementById('iframe');     // 监听a.html传来的hash值,再传给c.html     window.onhashchange = function () {         iframe.src = iframe.src location.hash;     }; </script>

1
2
3
4
5
6
7
8
9
<iframe id="iframe" src="http://www.domain1.com/c.html" style="display:none;"></iframe>
<script>
    var iframe = document.getElementById('iframe');
 
    // 监听a.html传来的hash值,再传给c.html
    window.onhashchange = function () {
        iframe.src = iframe.src location.hash;
    };
</script>

3.)c.html:(

<script>     // 监听b.html传来的hash值     window.onhashchange = function (卡塔尔国 {         // 再通过操作同域a.html的js回调,将结果传到         window.parent.parent.onCallback('hello: ' location.hash.replace('#user=', ''));     }; </script>

1
2
3
4
5
6
7
<script>
    // 监听b.html传来的hash值
    window.onhashchange = function () {
        // 再通过操作同域a.html的js回调,将结果传回
        window.parent.parent.onCallback('hello: ' location.hash.replace('#user=', ''));
    };
</script>

1.卡塔尔 能源跳转: A链接、重定向、表单提交

四、 window.name iframe跨域

window.name属性的特别之处:name值在不相同的页面(以致区别域名)加载后仍旧存在,而且能够支撑非常长的 name 值(2MB)。

1.)a.html:(

var proxy = function(url, callback卡塔尔(قطر‎ { var state = 0; var iframe = document.createElement('iframe'卡塔尔国; // 加载跨域页面 iframe.src = url; // onload事件会触发2次,第1次加载跨域页,并设有数据于window.name iframe.onload = function(卡塔尔(英语:State of Qatar) { if (state === 1卡塔尔(英语:State of Qatar) { // 第2次onload(同域proxy页卡塔尔(英语:State of Qatar)成功后,读取同域window.name中多少 callback(iframe.contentWindow.name卡塔尔; destoryFrame(卡塔尔(قطر‎; } else if (state === 0卡塔尔(英语:State of Qatar) { // 第1次onload(跨域页卡塔尔成功后,切换来同域代理页面 iframe.contentWindow.location = ''; state = 1; } }; document.body.appendChild(iframe卡塔尔; // 获取数据未来销毁那几个iframe,释放内部存款和储蓄器;那也保险了安全(不被其余域frame js访问) function destoryFrame(卡塔尔(قطر‎ { iframe.contentWindow.document.write(''卡塔尔(英语:State of Qatar); iframe.contentWindow.close(卡塔尔国; document.body.removeChild(iframe卡塔尔国; } }; // 诉求跨域b页面数据 proxy('', function(data){ alert(data); });

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
var proxy = function(url, callback) {
    var state = 0;
    var iframe = document.createElement('iframe');
 
    // 加载跨域页面
    iframe.src = url;
 
    // onload事件会触发2次,第1次加载跨域页,并留存数据于window.name
    iframe.onload = function() {
        if (state === 1) {
            // 第2次onload(同域proxy页)成功后,读取同域window.name中数据
            callback(iframe.contentWindow.name);
            destoryFrame();
 
        } else if (state === 0) {
            // 第1次onload(跨域页)成功后,切换到同域代理页面
            iframe.contentWindow.location = 'http://www.domain1.com/proxy.html';
            state = 1;
        }
    };
 
    document.body.appendChild(iframe);
 
    // 获取数据以后销毁这个iframe,释放内存;这也保证了安全(不被其他域frame js访问)
    function destoryFrame() {
        iframe.contentWindow.document.write('');
        iframe.contentWindow.close();
        document.body.removeChild(iframe);
    }
};
 
// 请求跨域b页面数据
proxy('http://www.domain2.com/b.html', function(data){
    alert(data);
});

2.)proxy.html:(http://www.domain1.com/proxy….)
个中代理页,与a.html同域,内容为空就能够。

3.)b.html:(

<script>     window.name = 'This is domain2 data!'; </script>

1
2
3
<script>
    window.name = 'This is domain2 data!';
</script>

小结:通过iframe的src属性由国外转向当地方,跨域数据即由iframe的window.name从异国传递到当地方。那些就高明地绕过了浏览器的跨域访谈约束,但还要它又是安全操作。

2.卡塔尔能源嵌入:<link>、<script>、<img>、<frame>等dom标签,还会有样式中background:url(卡塔尔(英语:State of Qatar)、@font-face(卡塔尔等公事外链

五、 postMessage跨域

postMessage是HTML5 XMLHttpRequest Level 第22中学的API,且是为数非常的少能够跨域操作的window属性之风度翩翩,它可用于消除以下位置的标题:
a.) 页面和其开辟的新窗口的数码传递
b.) 多窗口之间音信传递
c.) 页面与嵌套的iframe信息传递
d.) 上边七个现象的跨域数据传递

用法:postMessage(data,origin卡塔尔(英语:State of Qatar)方法接收几个参数
data: html5正经帮助任性基本类型或可复制的靶子,但部分浏览器只协理字符串,所以传参时最棒用JSON.stringify(卡塔尔(قطر‎类别化。
origin: 左券 主机 端口号,也得以安装为”*”,表示能够传递给自由窗口,假设要钦赐和前段时间窗口同源的话设置为”/”。

1.)a.html:(

<iframe id="iframe" src="" style="display:none;"></iframe> <script> var iframe = document.getElementById('iframe'卡塔尔(英语:State of Qatar); iframe.onload = function(卡塔尔(قطر‎ { var data = { name: 'aym' }; // 向domain2传送跨域数据 iframe.contentWindow.postMessage(JSON.stringify(data卡塔尔(英语:State of Qatar), ''卡塔尔(英语:State of Qatar); }; // 选拔domain2再次来到数据 window.addEventListener('message', function(e) { alert('data from domain2 ---> ' e.data卡塔尔国; }, false卡塔尔(英语:State of Qatar); </script>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<iframe id="iframe" src="http://www.domain2.com/b.html" style="display:none;"></iframe>
<script>      
    var iframe = document.getElementById('iframe');
    iframe.onload = function() {
        var data = {
            name: 'aym'
        };
        // 向domain2传送跨域数据
        iframe.contentWindow.postMessage(JSON.stringify(data), 'http://www.domain2.com');
    };
 
    // 接受domain2返回数据
    window.addEventListener('message', function(e) {
        alert('data from domain2 ---> ' e.data);
    }, false);
</script>

2.)b.html:(

<script> // 接受domain1的多寡 window.addEventListener('message', function(e卡塔尔(英语:State of Qatar) { alert('data from domain1 ---> ' e.data卡塔尔国; var data = JSON.parse(e.data卡塔尔; if (data卡塔尔国 { data.number = 16; // 管理后再发回domain1 window.parent.postMessage(JSON.stringify(data卡塔尔(英语:State of Qatar), ''); } }, false); </script>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<script>
    // 接收domain1的数据
    window.addEventListener('message', function(e) {
        alert('data from domain1 ---> ' e.data);
 
        var data = JSON.parse(e.data);
        if (data) {
            data.number = 16;
 
            // 处理后再发回domain1
            window.parent.postMessage(JSON.stringify(data), 'http://www.domain1.com');
        }
    }, false);
</script>

3.卡塔尔(英语:State of Qatar) 脚本供给: js发起的ajax央求、dom和js对象的跨域操作等

六、 跨域财富共享(COEnclaveS)

平时跨域供给:只服务端设置Access-Control-Allow-Origin就可以,前端无须设置。
带cookie须要:前后端都亟待设置字段,其余部要求注意:所带cookie为跨域乞求接口所在域的cookie,而非当前页。
时下,全体浏览器都扶助该意义(IE8 :IE8/9亟需接受XDomainRequest对象来支持CO奥迪Q5S)卡塔尔(قطر‎,CO牧马人S也已经化为主流的跨域技术方案。

 

1、 前端设置:

1.)原生ajax

// 前端安装是不是带cookie xhr.withCredentials = true;

1
2
// 前端设置是否带cookie
xhr.withCredentials = true;

演示代码:

var xhr = new XMLHttpRequest(卡塔尔国; // IE8/9需用window.XDomainRequest包容 // 前端安装是不是带cookie xhr.withCredentials = true; xhr.open('post', '', true); xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); xhr.send('user=admin'); xhr.onreadystatechange = function() { if (xhr.readyState == 4 && xhr.status == 200) { alert(xhr.responseText); } };

1
2
3
4
5
6
7
8
9
10
11
12
13
14
var xhr = new XMLHttpRequest(); // IE8/9需用window.XDomainRequest兼容
 
// 前端设置是否带cookie
xhr.withCredentials = true;
 
xhr.open('post', 'http://www.domain2.com:8080/login', true);
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
xhr.send('user=admin');
 
xhr.onreadystatechange = function() {
    if (xhr.readyState == 4 && xhr.status == 200) {
        alert(xhr.responseText);
    }
};

2.)jQuery ajax

$.ajax({ ... xhrFields: { withCredentials: true // 前端安装是或不是带cookie }, crossDomain: true, // 会让诉求头中隐含跨域的附加音信,但不会含cookie ... }卡塔尔;

1
2
3
4
5
6
7
8
$.ajax({
    ...
   xhrFields: {
       withCredentials: true    // 前端设置是否带cookie
   },
   crossDomain: true,   // 会让请求头中包含跨域的额外信息,但不会含cookie
    ...
});

3.)vue框架
在vue-resource封装的ajax组件中参预以下代码:

Vue.http.options.credentials = true

1
Vue.http.options.credentials = true

实际上我们多如牛毛所说的跨域是狭义的,是由浏览器同源计谋节制的后生可畏类央求场景。

2、 服务端设置:

若后端设置成功,前端浏览器调控台则不会现身跨域报错音讯,反之,表明没设成功。

1.)Java后台:

/* * 导入包:import javax.servlet.http.HttpServletResponse; * 接口参数中定义:HttpServletResponse response */ response.setHeader("Access-Control-Allow-Origin", ""卡塔尔(英语:State of Qatar); // 若有端口需写全(公约 域名 端口) response.setHeader("Access-Control-Allow-Credentials", "true"卡塔尔(قطر‎;

1
2
3
4
5
6
/*
* 导入包:import javax.servlet.http.HttpServletResponse;
* 接口参数中定义:HttpServletResponse response
*/
response.setHeader("Access-Control-Allow-Origin", "http://www.domain1.com");  // 若有端口需写全(协议 域名 端口)
response.setHeader("Access-Control-Allow-Credentials", "true");

2.)Nodejs后台示例:

var http = require('http'卡塔尔(قطر‎; var server = http.createServer(卡塔尔; var qs = require('querystring'卡塔尔国; server.on('request', function(req, res卡塔尔(英语:State of Qatar) { var postData = ''; // 数据块选取中 req.addListener('data', function(chunk卡塔尔国 { postData = chunk; }卡塔尔国; // 数据采纳完毕 req.addListener('end', function(卡塔尔国{ postData = qs.parse(postData卡塔尔国; // 跨域后台装置 res.writeHead(200, { 'Access-Control-Allow-Credentials': 'true', // 后端允许发送Cookie 'Access-Control-Allow-Origin': '', // 允许访谈的域(左券 域名 端口) 'Set-Cookie': 'l=a123456;帕特h=/;Domain=www.domain2.com;HttpOnly' // HttpOnly:脚本不可能读取cookie }卡塔尔; res.write(JSON.stringify(postData卡塔尔(قطر‎卡塔尔(英语:State of Qatar); res.end(卡塔尔(英语:State of Qatar); }卡塔尔(英语:State of Qatar); }卡塔尔(英语:State of Qatar); server.listen('8080'卡塔尔国; console.log('Server is running at port 8080...'卡塔尔;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
var http = require('http');
var server = http.createServer();
var qs = require('querystring');
 
server.on('request', function(req, res) {
    var postData = '';
 
    // 数据块接收中
    req.addListener('data', function(chunk) {
        postData = chunk;
    });
 
    // 数据接收完毕
    req.addListener('end', function() {
        postData = qs.parse(postData);
 
        // 跨域后台设置
        res.writeHead(200, {
            'Access-Control-Allow-Credentials': 'true',     // 后端允许发送Cookie
            'Access-Control-Allow-Origin': 'http://www.domain1.com',    // 允许访问的域(协议 域名 端口)
            'Set-Cookie': 'l=a123456;Path=/;Domain=www.domain2.com;HttpOnly'   // HttpOnly:脚本无法读取cookie
        });
 
        res.write(JSON.stringify(postData));
        res.end();
    });
});
 
server.listen('8080');
console.log('Server is running at port 8080...');

 

七、 nginx代理跨域

哪些是同源战略?

1、 nginx配置解决iconfont跨域

浏览器跨域访谈js、css、img等健康静态能源被同源计谋准许,但iconfont字体文件(eot|otf|ttf|woff|svg卡塔尔国例外,那时候可在nginx的静态财富服务器中投入以下配置。

location / { add_header Access-Control-Allow-Origin *; }

1
2
3
location / {
  add_header Access-Control-Allow-Origin *;
}

 

2、 nginx反向代理接口跨域

跨域原理: 同源战术是浏览器的安全攻略,不是HTTP合同的生龙活虎有的。服务器端调用HTTP接口只是使用HTTP合同,不会进行JS脚本,无需同源计策,也就空头支票赶过难点。

福如东海思路:通过nginx配置一个代理服务器(域名与domain1相近,端口差别)做跳板机,反向代理访谈domain2接口,並且能够顺便校订cookie中domain新闻,方便当前域cookie写入,达成跨域登入。

nginx具体安插:

#proxy服务器 server { listen 81; server_name www.domain1.com; location / { proxy_pass ; #反向代理 proxy_cookie_domain www.domain2.com www.domain1.com; #修改cookie里域名 index index.html index.htm; # 当用webpack-dev-server等中间件代理接口访谈nignx时,当时无浏览器参加,故没有同源节制,下边的跨域配置可不启用 add_header Access-Control-Allow-Origin ; #现阶段端只跨域不带cookie时,可为* add_header Access-Control-Allow-Credentials true; } }

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#proxy服务器
server {
    listen       81;
    server_name  www.domain1.com;
 
    location / {
        proxy_pass   http://www.domain2.com:8080;  #反向代理
        proxy_cookie_domain www.domain2.com www.domain1.com; #修改cookie里域名
        index  index.html index.htm;
 
        # 当用webpack-dev-server等中间件代理接口访问nignx时,此时无浏览器参与,故没有同源限制,下面的跨域配置可不启用
        add_header Access-Control-Allow-Origin http://www.domain1.com;  #当前端只跨域不带cookie时,可为*
        add_header Access-Control-Allow-Credentials true;
    }
}

1.卡塔尔(英语:State of Qatar) 前端代码示例:

var xhr = new XMLHttpRequest(卡塔尔(قطر‎; // 前端按键:浏览器是还是不是读写cookie xhr.withCredentials = true; // 访谈nginx中的代理服务器 xhr.open('get', '', true); xhr.send();

1
2
3
4
5
6
7
8
var xhr = new XMLHttpRequest();
 
// 前端开关:浏览器是否读写cookie
xhr.withCredentials = true;
 
// 访问nginx中的代理服务器
xhr.open('get', 'http://www.domain1.com:81/?user=admin', true);
xhr.send();

2.卡塔尔国 Nodejs后台示例:

var http = require('http'卡塔尔(英语:State of Qatar); var server = http.createServer(卡塔尔(英语:State of Qatar); var qs = require('querystring'卡塔尔(英语:State of Qatar); server.on('request', function(req, res卡塔尔(قطر‎ { var params = qs.parse(req.url.substring(2卡塔尔(英语:State of Qatar)卡塔尔; // 向前台写cookie res.writeHead(200, { 'Set-Cookie': 'l=a123456;Path=/;Domain=www.domain2.com;HttpOnly' // HttpOnly:脚本不可能读取 }卡塔尔国; res.write(JSON.stringify(params)卡塔尔(英语:State of Qatar); res.end(卡塔尔(英语:State of Qatar); }卡塔尔国; server.listen('8080'卡塔尔国; console.log('Server is running at port 8080...'卡塔尔;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
var http = require('http');
var server = http.createServer();
var qs = require('querystring');
 
server.on('request', function(req, res) {
    var params = qs.parse(req.url.substring(2));
 
    // 向前台写cookie
    res.writeHead(200, {
        'Set-Cookie': 'l=a123456;Path=/;Domain=www.domain2.com;HttpOnly'   // HttpOnly:脚本无法读取
    });
 
    res.write(JSON.stringify(params));
    res.end();
});
 
server.listen('8080');
console.log('Server is running at port 8080...');

同源战术/SOP(Same origin policy)是生机勃勃种约定,由Netscape公司1994年引进浏览器,它是浏览器最主题也最主旨的平安功效,假如缺点和失误了同源战术,浏览器超轻易遭逢XSS、CSFKuga等攻击。所谓同源是指”公约 域名 端口”三者风华正茂致,尽管四个例外的域名指向同贰个ip地址,也非同源。

八、 Nodejs中间件代理跨域

node中间件实现跨域代理,原理大概与nginx相通,都是由此启一个代理服务器,达成数据的转折。

 

1、 非vue框架的跨域(2次跨域)

应用node express http-proxy-middleware搭建叁个proxy服务器。

1.)前端代码示例:

var xhr = new XMLHttpRequest(卡塔尔(英语:State of Qatar); // 前端开关:浏览器是不是读写cookie xhr.withCredentials = true; // 访谈http-proxy-middleware代理服务器 xhr.open('get', '', true); xhr.send();

1
2
3
4
5
6
7
8
var xhr = new XMLHttpRequest();
 
// 前端开关:浏览器是否读写cookie
xhr.withCredentials = true;
 
// 访问http-proxy-middleware代理服务器
xhr.open('get', 'http://www.domain1.com:3000/login?user=admin', true);
xhr.send();

2.)中间件服务器:

var express = require('express'卡塔尔国; var proxy = require('http-proxy-middleware'卡塔尔(英语:State of Qatar); var app = express(卡塔尔(英语:State of Qatar); app.use('/', proxy({ // 代理跨域指标接口 target: '', changeOrigin: true, // 矫正响应头音讯,实现跨域并允许带cookie onProxyRes: function(proxyRes, req, res卡塔尔国 { res.header('Access-Control-Allow-Origin', ''卡塔尔国; res.header('Access-Control-Allow-Credentials', 'true'卡塔尔(قطر‎; }, // 改善响应音信中的cookie域名 cookieDomainRewrite: 'www.domain1.com' // 可感到false,表示不改过 }卡塔尔(英语:State of Qatar)卡塔尔(قطر‎; app.listen(3000卡塔尔(英语:State of Qatar); console.log('Proxy server is listen at port 3000...'卡塔尔国;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
var express = require('express');
var proxy = require('http-proxy-middleware');
var app = express();
 
app.use('/', proxy({
    // 代理跨域目标接口
    target: 'http://www.domain2.com:8080',
    changeOrigin: true,
 
    // 修改响应头信息,实现跨域并允许带cookie
    onProxyRes: function(proxyRes, req, res) {
        res.header('Access-Control-Allow-Origin', 'http://www.domain1.com');
        res.header('Access-Control-Allow-Credentials', 'true');
    },
 
    // 修改响应信息中的cookie域名
    cookieDomainRewrite: 'www.domain1.com'  // 可以为false,表示不修改
}));
 
app.listen(3000);
console.log('Proxy server is listen at port 3000...');

3.)Nodejs后台同(六:nginx)

同源计谋节制之下两种表现:

2、 vue框架的跨域(1次跨域)

采纳node webpack webpack-dev-server代理接口跨域。在付出意况下,由于vue渲染服务和接口代理服务都以webpack-dev-server同二个,所以页面与代理接口之间不再跨域,无须设置headers跨域音讯了。

webpack.config.js部分配置:

module.exports = { entry: {}, module: {}, ... devServer: { historyApiFallback: true, proxy: [{ context: '/login', target: '', // 代理跨域目的接口 changeOrigin: true, cookieDomainRewrite: 'www.domain1.com' // 可感到false,表示不改正 }], noInfo: true } }

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
module.exports = {
    entry: {},
    module: {},
    ...
    devServer: {
        historyApiFallback: true,
        proxy: [{
            context: '/login',
            target: 'http://www.domain2.com:8080',  // 代理跨域目标接口
            changeOrigin: true,
            cookieDomainRewrite: 'www.domain1.com'  // 可以为false,表示不修改
        }],
        noInfo: true
    }
}

 

九、 WebSocket商量跨域

WebSocket protocol是HTML5黄金时代种新的合计。它达成了浏览器与服务器全双工通讯,同期同意跨域通信,是server push手艺的生机勃勃种很好的实现。
原生WebSocket API使用起来不太平价,大家选取Socket.io,它很好地包裹了webSocket接口,提供了更简约、灵活的接口,也对不扶植webSocket的浏览器提供了向下包容。

1.)前端代码:

<div>user input:<input type="text"></div> <script src="./socket.io.js"></script> <script> var socket = io(''卡塔尔(قطر‎; // 连接成功拍卖 socket.on('connect', function(卡塔尔(英语:State of Qatar) { // 监听服务端新闻 socket.on('message', function(msg卡塔尔国 { console.log('data from server: ---> ' msg卡塔尔(英语:State of Qatar); }卡塔尔(قطر‎; // 监听服务端关闭 socket.on('disconnect', function(卡塔尔 { console.log('Server socket has closed.'卡塔尔; }卡塔尔国; }卡塔尔(قطر‎; document.getElementsByTagName('input'卡塔尔(英语:State of Qatar)[0].onblur = function() { socket.send(this.value); }; </script>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<div>user input:<input type="text"></div>
<script src="./socket.io.js"></script>
<script>
var socket = io('http://www.domain2.com:8080');
 
// 连接成功处理
socket.on('connect', function() {
    // 监听服务端消息
    socket.on('message', function(msg) {
        console.log('data from server: ---> ' msg);
    });
 
    // 监听服务端关闭
    socket.on('disconnect', function() {
        console.log('Server socket has closed.');
    });
});
 
document.getElementsByTagName('input')[0].onblur = function() {
    socket.send(this.value);
};
</script>

2.)Nodejs socket后台:

var http = require('http'卡塔尔(قطر‎; var socket = require('socket.io'卡塔尔; // 启http服务 var server = http.createServer(function(req, res卡塔尔国 { res.writeHead(200, { 'Content-type': 'text/html' }卡塔尔国; res.end(卡塔尔国; }卡塔尔国; server.listen('8080'卡塔尔国; console.log('Server is running at port 8080...'卡塔尔(英语:State of Qatar); // 监听socket连接 socket.listen(server卡塔尔国.on('connection', function(client卡塔尔国 { // 选用新闻 client.on('message', function(msg卡塔尔国 { client.send('hello:' msg卡塔尔(قطر‎; console.log('data from client: ---> ' msg卡塔尔国; }卡塔尔(قطر‎; // 断开管理 client.on('disconnect', function(卡塔尔(قطر‎ { console.log('Client socket has closed.'卡塔尔; }卡塔尔(英语:State of Qatar); }卡塔尔(英语:State of Qatar);

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
var http = require('http');
var socket = require('socket.io');
 
// 启http服务
var server = http.createServer(function(req, res) {
    res.writeHead(200, {
        'Content-type': 'text/html'
    });
    res.end();
});
 
server.listen('8080');
console.log('Server is running at port 8080...');
 
// 监听socket连接
socket.listen(server).on('connection', function(client) {
    // 接收信息
    client.on('message', function(msg) {
        client.send('hello:' msg);
        console.log('data from client: ---> ' msg);
    });
 
    // 断开处理
    client.on('disconnect', function() {
        console.log('Client socket has closed.');
    });
});

3 赞 13 收藏 3 评论

图片 1

1.卡塔尔(英语:State of Qatar) Cookie、LocalStorage 和 IndexDB 不大概读取

2.卡塔尔(قطر‎ DOM 和 Js对象不恐怕拿到

3.卡塔尔 AJAX 央求不可能发送

 

周边跨域场景

 

ULANDL                                      表达                    是或不是允许通讯

         同豆蔻梢头域名,分裂文件或路线           允许

 

         同生龙活虎域名,不相同端口                不容许

 

        同风流倜傥域名,分歧协商                差异意

 

           域名和域名对应相似ip              不准

 

           主域相近,子域分裂                不容许

 

        分歧域名                         不相同意

 

跨域技术方案

 

1、 通过jsonp跨域

2、 document.domain iframe跨域

3、 location.hash iframe

4、 window.name iframe跨域

5、 postMessage跨域

6、 跨域财富分享(COPRADOS)

7、 nginx代理跨域

8、 nodejs中间件代理跨域

9、 WebSocket共商跨域

 

一、 通过jsonp跨域

 

平日为了缓和web服务器的负荷,大家把js、css,img等静态财富分离到另大器晚成台独立域名的服务器上,在html页面中再通过相应的竹签从区别域名下加载静态能源,而被浏览器允许,基于此原理,大家得以经过动态创设script,再恳求三个带参网站实现跨域通讯。

 

1.)原生完成:

 

<script>

    var script = document.createElement('script');

    script.type = 'text/javascript';

 

    // 传参并钦定回调实行函数为onBack

    script.src = '';

    document.head.appendChild(script);

 

    // 回调推行函数

    function onBack(res) {

        alert(JSON.stringify(res));

    }

</script>

 

服务端重回如下(重回时即实行全局函数):

 

onBack({"status": true, "user": "admin"})

 

2.)jquery ajax:

 

$.ajax({

    url: '',

    type: 'get',

    dataType: 'jsonp',  // 央求格局为jsonp

    jsonpCallback: "onBack",    // 自定义回调函数名

    data: {}

});

 

3.)vue.js:

 

this.$http.jsonp('', {

    params: {},

    jsonp: 'onBack'

}).then((res) => {

    console.log(res);

})

 

后端node.js代码示例:

 

var querystring = require('querystring');

var http = require('http');

var server = http.createServer();

 

server.on('request', function(req, res) {

    var params = qs.parse(req.url.split('?')[1]);

    var fn = params.callback;

 

    // jsonp重回设置

    res.writeHead(200, { 'Content-Type': 'text/javascript' });

    res.write(fn   '('   JSON.stringify(params)   ')');

 

    res.end();

});

 

server.listen('8080');

console.log('Server is running at port 8080...');

 

jsonp劣势:只好促成get大器晚成种乞请。

 

二、 document.domain iframe跨域

 

此方案只限主域雷同,子域不一样的跨域应用处景。

 

达成原理:多少个页面都由此js强制设置document.domain为底工主域,就落到实处了同域。

 

1.)父窗口:()

 

<iframe id="iframe" src=";

<script>

    document.domain = 'domain.com';

    var user = 'admin';

</script>

 

2.)子窗口:()

 

<script>

    document.domain = 'domain.com';

    // 获取父窗口中变量

    alert('get js data from parent ---> '   window.parent.user);

</script>

 

三、 location.hash iframe跨域

 

贯彻原理: 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:()

 

<iframe id="iframe" src="" style="display:none;"></iframe>

<script>

    var iframe = document.getElementById('iframe');

 

    // 向b.html传hash值

    setTimeout(function() {

        iframe.src = iframe.src   '#user=admin';

    }, 1000);

    

    // 开放给同域c.html的回调方法

    function onCallback(res) {

        alert('data from c.html ---> '   res);

    }

</script>

 

2.)b.html:()

 

<iframe id="iframe" src="" style="display:none;"></iframe>

<script>

    var iframe = document.getElementById('iframe');

 

    // 监听a.html传来的hash值,再传给c.html

    window.onhashchange = function () {

        iframe.src = iframe.src   location.hash;

    };

</script>

 

3.)c.html:()

 

<script>

    // 监听b.html传来的hash值

    window.onhashchange = function () {

        // 再经过操作同域a.html的js回调,将结果传到

        window.parent.parent.onCallback('hello: '   location.hash.replace('#user=', ''));

    };

</script>

 

四、 window.name iframe跨域

 

window.name属性的特别之处:name值在差别的页面(以至区别域名)加载后依旧存在,并且能够支撑非常长的 name 值(2MB)。

 

1.)a.html:()

 

var proxy = function(url, callback) {

    var state = 0;

    var iframe = document.createElement('iframe');

 

    // 加载跨域页面

    iframe.src = url;

 

    // onload事件会触发2次,第1次加载跨域页,并存在数据于window.name

    iframe.onload = function() {

        if (state === 1) {

            // 第2次onload(同域proxy页卡塔尔(英语:State of Qatar)成功后,读取同域window.name中多少

            callback(iframe.contentWindow.name);

            destoryFrame();

 

        } else if (state === 0) {

            // 第1次onload(跨域页卡塔尔(قطر‎成功后,切换成同域代理页面

            iframe.contentWindow.location = '';

            state = 1;

        }

    };

 

    document.body.appendChild(iframe);

 

    // 获取数据现在销毁这一个iframe,释放内部存款和储蓄器;这也保证了安全(不被其余域frame js访谈)

    function destoryFrame() {

        iframe.contentWindow.document.write('');

        iframe.contentWindow.close();

        document.body.removeChild(iframe);

    }

};

 

// 央浼跨域b页面数据

proxy('', function(data){

    alert(data);

});

 

2.)proxy.html:(.

高级中学档代理页,与a.html同域,内容为空就能够。

 

3.)b.html:()

 

<script>

    window.name = 'This is domain2 data!';

</script>

 

小结:通过iframe的src属性由海外转向当地点,跨域数据即由iframe的window.name从异国传递到本地点。那几个就高明地绕过了浏览器的跨域访谈约束,但与此同期它又是高枕而卧操作。

 

五、 postMessage跨域

 

postMessage是HTML5 XMLHttpRequest Level 第22中学的API,且是微量能够跨域操作的window属性之意气风发,它可用来缓慢解决以下方面包车型客车难题:

a.) 页面和其展开的新窗口的多少传递

b.) 多窗口之间音信传递

c.) 页面与嵌套的iframe信息传递

d.) 下边多少个情景的跨域数据传递

 

用法:postMessage(data,origin卡塔尔方法接纳三个参数

data: html5标准补助恣意基本项目或可复制的对象,但一些浏览器只扶助字符串,所以传参时最棒用JSON.stringify(卡塔尔(قطر‎种类化。

origin: 公约 主机 端口号,也能够设置为”*”,表示能够传递给自由窗口,假使要钦定和脚下窗口同源的话设置为”/”。

 

1.)a.html:()

 

<iframe id="iframe" src="" style="display:none;"></iframe>

<script>      

    var iframe = document.getElementById('iframe');

    iframe.onload = function() {

        var data = {

            name: 'aym'

        };

        // 向domain2传送跨域数据

        iframe.contentWindow.postMessage(JSON.stringify(data), '');

    };

 

    // 接收domain2重临数据

    window.addEventListener('message', function(e) {

        alert('data from domain2 ---> '   e.data);

    }, false);

</script>

 

2.)b.html:()

 

<script>

    // 接收domain1的数据

    window.addEventListener('message', function(e) {

        alert('data from domain1 ---> '   e.data);

 

        var data = JSON.parse(e.data);

        if (data) {

            data.number = 16;

 

            // 管理后再发回domain1

            window.parent.postMessage(JSON.stringify(data), '');

        }

    }, false);

</script>

 

六、 跨域财富分享(CO本田UR-VS)

 

平常跨域诉求:只服务端设置Access-Control-Allow-Origin就可以,前端无须设置。

带cookie诉求:前后端都亟待设置字段,别的部须求注意:所带cookie为跨域要求接口所在域的cookie,而非当前页。

近年来,全部浏览器都扶助该意义(IE8 :IE8/9亟需选拔XDomainRequest对象来帮助COEnclaveS)卡塔尔,CO普拉多S也已经化为主流的跨域应用方案。

 

1、 前端设置:

 

1.)原生ajax

 

// 前端安装是不是带cookie

xhr.withCredentials = true;

 

亲自去做代码:

 

var xhr = new XMLHttpRequest(); // IE8/9需用window.XDomainRequest兼容

 

// 前端安装是还是不是带cookie

xhr.withCredentials = true;

 

xhr.open('post', '', true);

xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');

xhr.send('user=admin');

 

xhr.onreadystatechange = function() {

    if (xhr.readyState == 4 && xhr.status == 200) {

        alert(xhr.responseText);

    }

};

 

2.)jQuery ajax

 

$.ajax({

    ...

   xhrFields: {

       withCredentials: true    // 前端安装是不是带cookie

   },

   crossDomain: true,   // 会让诉求头中蕴藏跨域的附加音讯,但不会含cookie

    ...

});

 

3.)vue框架

 

在vue-resource封装的ajax组件中步入以下代码:

 

Vue.http.options.credentials = true

 

2、 服务端设置:

 

若后端设置成功,前端浏览器调控台则不会并发跨域报错消息,反之,表达没设成功。

 

1.)Java后台:

 

/*

* 导入包:import javax.servlet.http.HttpServletResponse;

* 接口参数中定义:HttpServletResponse response

*/

response.setHeader("Access-Control-Allow-Origin", ""卡塔尔(قطر‎;  // 若有端口需写全(协议 域名 端口)

response.setHeader("Access-Control-Allow-Credentials", "true");

 

2.)Nodejs后台示例:

 

var http = require('http');

var server = http.createServer();

var qs = require('querystring');

 

server.on('request', function(req, res) {

    var postData = '';

 

    // 数据块接纳中

    req.addListener('data', function(chunk) {

        postData  = chunk;

    });

 

    // 数据选用完成

    req.addListener('end', function() {

        postData = qs.parse(postData);

 

        // 跨域后台装置

        res.writeHead(200, {

            'Access-Control-Allow-Credentials': 'true',     // 后端允许发送Cookie

            'Access-Control-Allow-Origin': '',    // 允许访谈的域(公约 域名 端口)

            'Set-Cookie': 'l=a123456;Path=/;Domain=www.domain2.com;HttpOnly'   // HttpOnly:脚本不可能读取cookie

        });

 

        res.write(JSON.stringify(postData));

        res.end();

    });

});

 

server.listen('8080');

console.log('Server is running at port 8080...');

 

七、 nginx代理跨域

 

1、 nginx配置解决iconfont跨域

 

浏览器跨域访谈js、css、img等常规静态财富被同源战略承认,但iconfont字体文件(eot|otf|ttf|woff|svg卡塔尔(英语:State of Qatar)例外,当时可在nginx的静态财富服务器中参预以下配置。

 

location / {

  add_header Access-Control-Allow-Origin *;

}

 

2、 nginx反向代理接口跨域

 

跨域原理: 同源战术是浏览器的安全战略,不是HTTP契约的豆蔻梢头部分。服务器端调用HTTP接口只是接收HTTP左券,不会履行JS脚本,无需同源计谋,也就空中楼阁越过难点。

 

贯彻思路:通过nginx配置贰个代理服务器(域名与domain1相像,端口不相同)做跳板机,反向代理访问domain2接口,况且能够顺便校勘cookie中domain音信,方便当前域cookie写入,达成跨域登入。

 

nginx具体配置:

 

#proxy服务器

server {

    listen       81;

    server_name  www.domain1.com;

 

    location / {

        proxy_pass   ;  #反向代理

        proxy_cookie_domain www.domain2.com www.domain1.com; #修改cookie里域名

        index  index.html index.htm;

 

        # 当用webpack-dev-server等中间件代理接口访谈nignx时,那时候无浏览器加入,故未有同源限定,上边包车型大巴跨域配置可不启用

        add_header Access-Control-Allow-Origin ;  #一时端只跨域不带cookie时,可为*

        add_header Access-Control-Allow-Credentials true;

    }

}

 

1.卡塔尔(英语:State of Qatar)前端代码示例:

 

var xhr = new XMLHttpRequest();

 

// 前端按钮:浏览器是不是读写cookie

xhr.withCredentials = true;

 

// 访谈nginx中的代理服务器

xhr.open('get', '', true);

xhr.send();

 

2.卡塔尔国 Nodejs后台示例:

 

var http = require('http');

var server = http.createServer();

var qs = require('querystring');

 

server.on('request', function(req, res) {

    var params = qs.parse(req.url.substring(2));

 

    // 向前台写cookie

    res.writeHead(200, {

        'Set-库克ie': 'l=a123456;Path=/;Domain=www.domain2.com;HttpOnly'   // HttpOnly:脚本不能够读取

    });

 

    res.write(JSON.stringify(params));

    res.end();

});

 

server.listen('8080');

console.log('Server is running at port 8080...');

 

八、 Nodejs中间件代理跨域

 

node中间件完毕跨域代理,原理大约与nginx相近,都以由此启叁个代理服务器,完毕数量的转变。

 

1、 非vue框架的跨域(2次跨域)

 

行使node express http-proxy-middleware搭建多个proxy服务器。

 

1.)前端代码示例:

 

var xhr = new XMLHttpRequest();

 

// 前端按键:浏览器是还是不是读写cookie

xhr.withCredentials = true;

 

// 访谈http-proxy-middleware代理服务器

xhr.open('get', '', true);

xhr.send();

 

2.)中间件服务器:

 

var express = require('express');

var proxy = require('http-proxy-middleware');

var app = express();

 

app.use('/', proxy({

    // 代理跨域指标接口

    target: '',

    changeOrigin: true,

 

    // 改正响应头音讯,实现跨域并允许带cookie

    onProxyRes: function(proxyRes, req, res) {

        res.header('Access-Control-Allow-Origin', '');

        res.header('Access-Control-Allow-Credentials', 'true');

    },

 

    // 校正响应音信中的cookie域名

    cookieDomainRewrite: 'www.domain1.com'  // 可以为false,表示不改进

}));

 

app.listen(3000);

console.log('Proxy server is listen at port 3000...');

 

3.)Nodejs后台同(六:nginx)

 

2、 vue框架的跨域(1次跨域)

 

使用node webpack webpack-dev-server代理接口跨域。在开拓条件下,由于vue渲染服务和接口代理服务都是webpack-dev-server同一个,所以页面与代理接口之间不再跨域,无须设置headers跨域消息了。

 

webpack.config.js部分配置:

 

module.exports = {

    entry: {},

    module: {},

    ...

    devServer: {

        historyApiFallback: true,

        proxy: [{

            context: '/login',

            target: '',  // 代理跨域指标接口

            changeOrigin: true,

            cookieDomainRewrite: 'www.domain1.com'  // 可认为false,表示不改过

        }],

        noInfo: true

    }

}

 

九、 WebSocket和睦跨域

 

WebSocket protocol是HTML5黄金年代种新的商业事务。它实现了浏览器与服务器全双工通讯,同一时间允许跨域通信,是server push技巧的风度翩翩种很好的兑现。

原生WebSocket API使用起来不太方便,大家运用Socket.io,它很好地卷入了webSocket接口,提供了更简便易行、灵活的接口,也对不援助webSocket的浏览器提供了向下包容。

 

1.)前端代码:

 

<div>user input:<input type="text"></div>

<script src="./socket.io.js"></script>

<script>

var socket = io('');

 

// 连接成功拍卖

socket.on('connect', function() {

    // 监听服务端音讯

    socket.on('message', function(msg) {

        console.log('data from server: ---> '   msg);

    });

 

    // 监听服务端关闭

    socket.on('disconnect', function() {

        console.log('Server socket has closed.');

    });

});

 

document.getElementsByTagName('input')[0].onblur = function() {

    socket.send(this.value);

};

</script>

 

2.)Nodejs socket后台:

 

var http = require('http');

var socket = require('socket.io');

 

// 启http服务

var server = http.createServer(function(req, res) {

    res.writeHead(200, {

        'Content-type': 'text/html'

    });

    res.end();

});

 

server.listen('8080');

console.log('Server is running at port 8080...');

 

// 监听socket连接

socket.listen(server).on('connection', function(client) {

    // 接受新闻

    client.on('message', function(msg) {

        client.send('hello:'   msg);

        console.log('data from client: ---> '   msg);

    });

 

    // 断开管理

    client.on('disconnect', function() {

        console.log('Client socket has closed.');

    });

});

 

本文由星彩网app下载发布于前端技术,转载请注明出处:前端常见跨域解决方案

TAG标签:
Ctrl+D 将本页面保存为书签,全面了解最新资讯,方便快捷。