标签:
这几天看了鬼道师兄的《跨终端Web》这本书,该书从解决实际业务出发,讲述了跨终端的优势与未来,受益良多。其中,书中第九章介绍了作者在阿里内部的一个参赛作品Storage,该作品巧妙的使用了跨域知识,让我见识到跨域其实不仅仅是
JSONP
。以前,对前端跨域这块或多或少有点了解,但真正动手实践的不是很多。于是,这段时间我好好整理了常用跨域方法的具体实现。本文,主要介绍了JSONP
和CORS
的实现方式。
相关概念:
a.com
域名下的js无法操作b.com
或是c.a.com
域名下的对象注意:
ip
上(“URL的首部”指window.location.protocol +window.location.host
,也可以理解为“Domains, protocols and ports must match”)相关配置:为了演示效果,在hosts文件里面添加如下内容
127.0.0.1 www.myapp.com
127.0.0.1 sample.myapp.com
127.0.0.1 www.otherapp.com
注意:测试demo基于NodeJS
的Express4.X
框架,且端口设置为80
JSONP
也叫填充式JSON
,是应用JSON
的一种新方法,只不过是被包含在函数调用中的JSON
(如:callback({"name", "chenjun"});
)。JSONP
由两部分组成:回调函数和数据。回调函数是当响应到来时应该在页面中调用的函数,而数据就是传入回调函数中的JSON
数据
跨域原理:利用<script>
标签没有跨域限制,实现跨域目的
访问页面:jsonp_test.ejs
<script>
function dosomething(jsondata) {
alert(jsondata.name + " " + jsondata.age);
}
</script>
<script src="http://www.otherapp.com/jsonp_data?callback=dosomething"></script>
后台路由:index.js
/* JSONP Test */
router.get(‘/jsonp_test‘, function(req, res) {
res.render(‘jsonp/jsonp_test‘);
});
router.get(‘/jsonp_data‘, function(req, res) {
var callback = req.query.callback;
var data = { name: "chenjun", age: "25" };
var str = callback + ‘(‘ + JSON.stringify(data) + ‘)‘; //jsonp
res.end(str);
});
效果:
JSONP优缺点:
XMLHttpRequest
对象实现的Ajax请求那样受到同源策略的限制;它的兼容性更好,在更加古老的浏览器中都可以运行;并且在请求完毕后可以通过调用callback的方式回传结果GET
请求而不支持POST
等其它类型的HTTP请求;它只支持跨域HTTP请求这种情况,不能解决不同域的两个页面之间如何进行JS调用的问题CORS
(Cross-Origin Resource Sharing)跨域资源共享,定义了必须在访问跨域资源时,浏览器与服务器应该如何沟通。
跨域原理:CORS
背后的基本思想就是使用自定义的HTTP头部让浏览器与服务器进行沟通,从而决定请求或响应是应该成功还是失败
浏览器支持情况:
Chrome,Firefox,Opera和Safari都使用XMLHttpRequest2
对象。 Internet Explorer使用了类似的XDomainRequest
对象,其工作原理和XMLHttpRequest
大致相同,但增加了额外的安全预防措施。
访问页面:cors_test.ejs
// 创建XHR 对象.
function createCORSRequest(method, url) {
var xhr = new XMLHttpRequest();
if ("withCredentials" in xhr) {
// XHR for Chrome/Firefox/Opera/Safari.
xhr.open(method, url, true);
} else if (typeof XDomainRequest != "undefined") {
// XDomainRequest for IE.
xhr = new XDomainRequest();
xhr.open(method, url);
} else {
// 不支持CORS.
xhr = null;
}
return xhr;
}
// 发起CORS请求
function makeCorsRequest() {
var url = ‘http://www.otherapp.com/cors_data‘;
var xhr = createCORSRequest(‘GET‘, url);
if (!xhr) {
alert(‘CORS not supported!‘);
return;
}
// 响应处理
xhr.onload = function() {
var text = xhr.responseText;
alert(text);
}
xhr.onerror = function() {
alert(‘Woops, there was an error making the request.‘);
}
xhr.send();
}
makeCorsRequest();
后台路由:index.js
/* CORS Test */
router.get(‘/cors_test‘, function(req, res) {
res.render(‘cors/cors_test‘);
});
router.get(‘/cors_data‘, function(req, res) {
var data = { name: "chenjun", age: "25" };
// 设置响应头
res.setHead(‘Access-Control-Allow-Origin‘, ‘*‘);
res.end(JSON.stringify(data));
});
效果:
CORS优缺点:
测试源码请戳这!下面一篇文章将介绍document.domain
、URL.hash
、cross-fragment
、window.name
和postMessage
这五种方式的跨域实现。
标签:
原文地址:http://www.cnblogs.com/daqianduan/p/4625536.html