JSONP
JSON with padding ,是一种借助于script 标签发送跨域请求的技巧。
其原理就是在客户端接住 script 标签请求服务端的一个动态网页(PHP文件),服务端的这个动态网页返回一段带有函数调用的JavaScript 全局函数调用的脚本,将原本需要返回给客户端的数据传递进去。
客户端 https://blog.csdn.net/KleyChan/users-list.html
<script src="https://blog.csdn.net/KleyChan/users.php?callback=foo"></script>
原生代码:
<script>
var script = document.createElement("script");
script.src = "https://blog.csdn.net/KleyChan/users.php";
document.body.appendChild(script);
function foo(res){
console.log(res)
}
</script>
封装函数代码:
<script>
function jsonp(url, params, callback){
if (typeof params === 'object') {
var temArr = [];
for(var key in params){
var value = params[key];
temArr.push (key + '=' + value);
}
params = temArr.join('&');
}
var script = document.createElement("script");
// 申明一个变量函数名,保证每次请求的callback函数名不一样
var fun_name = 'jsonp_' + Date.now() +Math.random().toString().substr(2, 5);
script.src = url+ '?'+ params + "&callback=" +fun_name;
document.body.appendChild(script);
window[fun_name] = function (res){
callback(res);
// 每次用完 删除函数,删除标签
// 为什么函数也要删除?? 全局函数,避免污染
delete window[fun_name];
document.body.removeChild(script);
}
}
</script>
// 函数调用
jsonp ('https://blog.csdn.net/KleyChan/users.php',
{id: 1111},function(res){
console.log(res);
})
jQuery 也把jsonp封装成函数:
<script>
// 这个其实跟ajax 没有任何关系
$.ajax({
url: 'https://blog.csdn.net/KleyChan/users.php',
data: {id:11111},
// 区别就是dataType: 'jsonp'
dataType: 'jsonp',
success: function(res){
console.log(res);
}
})
</script>
服务端https://blog.csdn.net/KleyChan/users.php?callback=foo 返回结果
foo(['我','是','数据'])
总结:
由于XMLHttpRequest 无法发送不同源地址之间的跨域请求,所以我们必须要另寻他法,script 这种方案就是我们最终选择的方式,我们把这种方式称之为JSONP ,如果你不了解原路,先记住怎么用,多用一段时间再来看原理。
问题:
- JSONP 需要服务端的配合,服务端按照客服端的要求返回一段JavaScript 调用客户端的函数
- 只能发送GET 请求
- 注意JSONP 用的是script 标签,跟AJAX 提供的XMLHttpRequest 没有任何关系!!!
jQuery 中使用JSONP 就是将dataType 设置为jsonp。
CORS
Cross Origin Resource Share, 跨域资源共享
它允许浏览器向跨源服务器,发出XMLHttpRequest请求,从而克服了AJAX只能同源使用的限制。 CORS需要浏览器和服务器同时支持。目前,所有浏览器都支持该功能,IE浏览器不能低于IE10。 整个CORS通信过程,都是浏览器自动完成,不需要用户参与。对于开发者来说,CORS通信与同源的AJAX通信没有差别,代码完全一样。浏览器一旦发现AJAX请求跨源,就会自动添加一些附加的头信息,有时还会多出一次附加的请求,但用户不会有感觉。
因此,实现CORS通信的关键是服务器。只要服务器实现了CORS接口,就可以跨源通信。
在php中,通过下面代码给客户端设置一个响应头,浏览器响应时就会知道允许跨域了
// 允许所有网站跨域访问该网站
header('Access-Control-Allow-Origin: *')
//只允许某个地址(百度
)跨域访问该网站
header( 'Access-Control-Allow-Origin:http://baidu.com' )
这种方案无需客户端做出任何变化(客户端不用改代码),只是在被请求的服务端响应的时候添加一个Access-Control-Allow-Origin 的响应头,表示这个资源是否允许指定域请求。
jsonp方式和cors方式的区别
- jsonp是jquery提供的跨域方式
- cors是w3c提供的一个跨域标准
——————————————————————
- jsonp只支持get方式的跨域
- cors支持get和post方式的跨域
——————————————————————
- jsonp支持所有的浏览器(因为所有浏览器都可以使用script标签发送请求)
- cors不支持IE10以下的浏览器
尽管这两种跨域方法可以解决跨域的问题,但两者的缺点都是非常依赖服务端的操作。