跨域解决方案之 jsonp
大家好,这里是修真院前端小课堂,今天给大家分享的是
《跨域解决方案之 jsonp》
1. 背景介绍
所有支持 Javascript 的浏览器都会使用同源策略这个安全策略。导致我们无法直接访问非同源的链接,无法取得非同源的数据,但在项目中我们的数据经常写在另一个源中,于是我们需要突破同源限制,取得其他源的数据,这就叫跨域。
2. 知识剖析
常见的跨域方法有:
- jsonp, 利用了 src 属性可以跨域的特性
- document.domain 跨子域
- Access Control, 服务器端发送 Access-Control-Allow-Origin 响应头,规定请求的域名的访问权限
- nginx 反向代理,客户端 nginx 拦截代码中虚假的 http 请求,替换成正确的 http
如何算不同的域?
- 不同域名
- 同一域名,不同端口
- 同一域名,不同协议
- 域名和域名对应 ip
- 主域相同,子域不同
- 同一域名,不同二级域名
3. 常见问题
jsonp 是如何实现跨域的
4. 解决方案
有两个文件处于不同域中:
A.html
<script type="text/javascript">
//回调函数
function callback(data) {
alert(data.message);
}
</script>
<script type = "text/javascript" src ="http://localhost:20002/B.js"></script>
B.js
//调用callback函数,并以json数据形式作为阐述传递,完成回调
callback({message: "success"});
结果会 alert “success”,这就是 jsop 的基本原理
5. 编码实战
客户端:
<script>
//显示后台返回数据的一个属性
function jsonp(data) {
//alert传入的data数组项中的一个属性
alert(JSON.parse(data)[0].location);
}
//添加<script>标签的方法
function addScriptTag(src) {
var script = document.createElement('script');
script.setAttribute("type", "text/javascript");
script.src = src;
document.body.appendChild(script);
}
//防止script标签放在头部运行时,body还未渲染
window.onload = function () {
//将数据从url中提取出来,便于添加数据。
var name = "冯强", age = 24, callback = "jsonp";
addScriptTag("http://59.110.174.154/test/test1.js?name=" + name + "&age=" + age + "&callback=" + callback);
}
</script>
服务器端:
//定义一些变量
var name,age,callback,data=[];
//遍历script标签
[].forEach.call(document.scripts, function (val, index, arr) {
if (val.src) {
//使用正则表达式匹配url字符串,并在回调函数中将我们需要的参数传递给变量
decodeURI(val.src).replace(/.*\?name=(.*)&age=(.*)&callback=(.*)/g, function (match, p1, p2,p3,offset,string) {
name=p1;
age=p2;
callback=p3;
});
}
});
//数据库的一段JSON代码
var json=[
{"name":"小宇","age":"24","location":"襄阳"},
{"name":"恒光","age":"24","location":"益阳"},
{"name":"冯强","age":"24","location":"黄冈"}
]
//遍历json,查询符合参数的项,屏添加到data数组中
json.forEach(function(val,index,arr){
if(val.name===name&&val.age===age){
data.push(json[index]);
}
})
//JSON化data数组
data=JSON.stringify(data);
//使用eval解析callback函数名,并传入data参数,执行函数
eval(callback)(data);
6. 扩展思考
jsonp 跨域有什么优缺点?
优点:兼容性很好好,可以在古老的浏览器中运行,
缺点:它只支持 GET 请求而不支持 POST 等其它类型的 HTTP 请求。
jsonp 和 ajax 有什么关系?
ajax 是通过操作 XMLHttpRequest 对象发送请求,获取返回的数据。JSONP 的全称为 JSON
with Padding,Padding 指的就是包裹在 JSON 外层的回调函数。从刚才的例子中,咱们发现 JSONP 并没有操作 XMLHttpRequest,因此 jsonp 和 ajax 没有任何关系。
如何用 jQuery 实现 JSONP
前端代码:
$.ajax({
url: "http://tonghuashuo.github.io/test/jsonp.txt",
dataType: 'jsonp',
jsonp: "callback",
jsonpCallback: "dosomething"
})
.done(function (res) {
console.log("success");
console.log(res);
})
.fail(function (res) {
console.log("error");
console.log(res);
});
这里使用了ajax这个方法,但实际上jsonp和ajax没有任何关系,只是因为jsonp请求和ajax请求相似,jquery在这里有误导之嫌。
7. 参考文献
【更多内容,可以加入IT交流群565734203与大家一起讨论交流】
【这里是技能树·IT修真院:IT修真院官网,初学者转行到互联网的聚集地】