Appearance
JSONP
JSONP是一种跨域共享资源的方法。
很多人会好奇JSONP和JSON是什么关系,JSONP是JSON with padding的缩写,即填充式JSON或参数式JSON,是被包含在函数调用中的JSON,如下面的样子:
js
callback({"name": "Chong"});
JSONP是通过动态<script>元素来实现的,使用时可以为src属性指定一个跨域URL。由于浏览器加载脚本是不受同源规则限制的,所以即使是跨域的URL同样可以发送请求。因为JSONP是有效的JavaScript代码,所以再请求完成后,即在JSONP响应加载到页面中以后,就会立即执行。
示例代码:
js
function handleResponse(response){
alert("您的IP地址是 " + response.ip);
}
var script = document.createElement("script");
script.src = "http://freegeoip.net/json/?callback=handleResponse";
document.body.insertBefore(script, document.body.firstChild);
所以总结一下JSONP的实现方式:
- 向当前页面中动态插入一个<script>元素,src属性设置为请求地址,并在地址中指定好回调函数
- js代码中预先定义好jsonp的回调函数
- 请求完成后,会立即调用预先指定好的jsonp回调,并将数据以json的格式传递到回调中。
JSONP之所以可以实现跨域,依赖的是下面的条件:
- 浏览器请求脚本是不受同源规则限制的
- <script>元素加载完成的脚本会立即执行
需要注意的是,JSONP是需要服务端配合的,因为JSONP返回的是一段代码。
JSONP服务器端设置
js
//通过request事件来响应request请求
server.on('request',function(req, res){
var urlPath = url.parse(req.url).pathname;
var qs = querystring.parse(req.url.split('?')[1]);
if(urlPath === '/jsonp' && qs.callback){
res.writeHead(200,{'Content-Type':'application/json;charset=utf-8'});
var data = {
"name": "Monkey"
};
data = JSON.stringify(data);
var callback = qs.callback+'('+data+');';
res.end(callback);
}
else{
res.writeHead(200, {'Content-Type':'text/html;charset=utf-8'});
res.end('Hell World\n');
}
});
注意点:
- jsonp 一般使用get,为防止浏览器缓存需要设置Cache-Control为no-cache
- 服务器端需要返回JSON格式的数据。
对比
优点:
- 简单易用,浏览器支持好。
缺点:
- JSONP是从其他域中加载代码并执行,所以存在很多安全隐患,如果其他服务器在响应中夹带恶意代码的话,没有办法防范。
- JSONP难以确定请求失败的情况。HTML5中给<script>元素增加了一个onerror事件,但是还是有浏览器不支持。
- 只能发送GET请求
问题
1. jsonp为什么不支持post方法
因为其使用的是script脚本的方式获取数据,其只能是get。