document.domain降域
我们为静态服务器设置了两个域名分别为a.both.com
和b.both.com
,并设置了两个静态网页,分别为a.html
和b.html
,在a网页中内嵌了b网页,iframe的src设置为b.both.com
,并在a网页中显示b网页中的信息,网页代码如下:
//a.html
<h1>This is a.html page</h1>
<iframe src="http://b.both.com:8080/b.html" frameborder="1"></iframe>
<script>
var h = document.querySelector('h1');
var ele = document.createElement('p');
var iframe = document.querySelector('iframe');
iframe.onload = function(){
var str = iframe.contentWindow.data;
var text = document.createTextNode(str);
ele.appendChild(text);
h.after(ele);
}
</script>
//b.html
<h1>This is b.html page</h1>
<script>
window.data = 'information in b.html';
</script>
我们通过a.both.com
域名,访问a.html
网页,实现跨域,此时网页并没有显示从b网页获取data信息,并且报错了
a.html``b.html
网页中都添加document.domain = 'both.com';
实现降域,以便跨域访问信息,得到如下效果:JSONP
JSONP方法是网页通过添加一个<script>元素,向服务器请求 JSON 数据,这种做法不受同源政策限制;服务器收到请求后,将数据放在一个指定名字的回调函数里传回来。
我们创建了静态服务器,域名修改为a.com
和b.com
,通过域名a.com
访问域名为http://b.com:8080
的资源,有如下代码:
//server.js
var http = require('http')
var fs = require('fs')
var path = require('path')
var url = require('url')
http.createServer(function(req, res){
var pathObj = url.parse(req.url, true)
switch (pathObj.pathname) {
case '/getInfo':
var info = ['This','is','information','from','server'];
res.setHeader('Content-Type','text/json; charset=utf-8')
if(pathObj.query.callback){
res.end(pathObj.query.callback + '(' + JSON.stringify(info) + ')')
}else{
res.end(JSON.stringify(info))
}
break;
default:
fs.readFile(path.join(__dirname, pathObj.pathname), function(e, data){
if(e){
res.writeHead(404, 'not found')
res.end('<h1>404 Not Found</h1>')
}else{
res.end(data)
}
})
}
}).listen(8080)
//index.html
<h1>CORS</h1>
<script>
function showData(data){
for(var i = 0; i < data.length; i++){
console.log(data[i]);
}
}
</script>
<script src="http://b.com:8080/getInfo?callback=showData"></script>
可以得到我们想要的数据
CORS
CORS 全称是跨域资源共享(Cross-Origin Resource Sharing),是一种 ajax 跨域请求资源的方式,支持现代浏览器,IE支持10以上。 实现方式很简单,当你使用 XMLHttpRequest
发送请求时,浏览器发现该请求不符合同源策略,会给该请求加一个请求头:Origin,后台进行一系列处理,如果确定接受请求则在返回结果中加入一个响应头:Access-Control-Allow-Origin;
浏览器判断该相应头中是否包含 Origin 的值,如果有则浏览器会处理响应,我们就可以拿到响应数据,如果不包含浏览器直接驳回,这时我们无法拿到响应数据。所以 CORS 的表象是让你觉得它与同源的 ajax 请求没啥区别,代码完全一样。
//index.html
<h1>CORS</h1>
<script>
var xhr = new XMLHttpRequest();
xhr.open('GET', 'http://b.com:8080/getInfo', true);
xhr.send();
xhr.onload = function(){
console.log(JSON.parse(xhr.responseText));
}
</script>
//server.js
var http = require('http')
var fs = require('fs')
var path = require('path')
var url = require('url')
http.createServer(function(req, res){
var pathObj = url.parse(req.url, true)
switch (pathObj.pathname) {
case '/getInfo':
var info = ['This','is','information','from','server'];
res.setHeader('Access-Control-Allow-Origin','http://a.com:8080')
res.setHeader('Content-Type','text/json; charset=utf-8')
if(pathObj.query.callback){
res.end(pathObj.query.callback + '(' + JSON.stringify(info) + ')')
}else{
res.end(JSON.stringify(info))
}
break;
default:
fs.readFile(path.join(__dirname, pathObj.pathname), function(e, data){
if(e){
res.writeHead(404, 'not found')
res.end('<h1>404 Not Found</h1>')
}else{
res.end(data)
}
})
}
}).listen(8080)
效果图如下:
请求与响应文件:
可以发现响应头的
Access-Control-Allow-Origin
和请求头的Origin
是一致的,所以可以实现跨域访问。