京东中关于jsonp的运用
以商品详情页为例:
文件头部出现很多jsonp的调用:
对于这个jsonp的函数回调放在iplocation_server.js这个文件中
//stock callback function getProvinceStockCallback(result) { var stockdesc="<strong>现货</strong>"; if (result.stock) { if(result.stock.D&&result.stock.D.id){ pageConfig.product.popInfo = result; } stockdesc = (result.stock.StockStateName=="统计中"|| result.stock.StockStateName=="无货")?"<strong class='store-over'>无货</strong>":("<strong>"+result.stock.StockStateName+"</strong>"); $("#store-selector .text div").html(currentLocation); pageConfig.product.yfinfo={}; if(result.stock.D&&result.stock.D.prompt){ var proarray=result.stock.D.prompt.split("|"); if (proarray[0]&&new Number(proarray[0])>0){ pageConfig.product.yfinfo={nofree:true,cash:proarray[0]}; } if(proarray[1]){ pageConfig.product.yfinfo.service=proarray[1]; } } $("#store-prompt").html(stockdesc+","+$.getStockDesc(result.stock) +(pageConfig.product.yfinfo.nofree?",<span style='cursor:pointer' title='一个店铺购买多件商品,只收取一次运费'>运费:<span style='color:#f00;'>¥"+pageConfig.product.yfinfo.cash+"</span><span>":"")); $.getDeliver(result.stock); SetNotifyByNoneStock(result.stock.StockState); } if (pageConfig.product.skuid>1000000000){ if(!$._ptload){ $._ptload=true; window._showPopTemplete=function(r){ if(result.stock.StockState==36){ if(r&&r.reserveDeliveryDay){ $._ptloadcon=r.reserveDeliveryDay; $("#store-prompt").html(stockdesc+","+"此商品为预订商品,下单后在"+$._ptloadcon); } } if(r&&r.wareTemplateContent)$("<div>"+r.wareTemplateContent+"</div>").insertBefore("#product-detail-1 .detail-content:first"); if(r&&r.wareTemplateBottomContent)$("<div>"+r.wareTemplateBottomContent+"</div>").insertAfter("#product-detail-1 .detail-content:last"); }; $.getJSONP("http://rms.shop.360buy.com/json/wareTemplate/queryWareTemplateContent.action?skuId="+pageConfig.product.skuid+"&jsoncallback=_showPopTemplete",_showPopTemplete); }else{ if($._ptloadcon)$("#store-prompt").html(stockdesc+","+"此商品为预订商品,下单后在"+$._ptloadcon); } } }
为啥这样调用:因为他能解决js跨域的问题;
补充知识:
JSONP原理及最简单的JSONP实现 (http://blog.163.com/hurricane_tx@126/blog/static/23850652009227198886/)
1) 什么是JSONP?
JSONP是一个非官方的协议,它允许在服务器端集成Script tags返回至客户端,通过javascript callback的形式实现跨域访问(这仅仅是JSONP简单的实现形式)。
2) 如何使用JSONP?
1. 在客户端调用提供JSONP支持的URL Service,获取JSONP格式数据。
比如客户想访问http://www.yiwuku.com/myService.aspx?jsonp=callbackFunction
假设客户期望返回JSON数据:[“customername1","customername2"]
那么直正返回到客户端的Script Tags: callbackFunction([“customername1","customername2"])
可能的调用方式:
<script type="text/javascript" src="http://www.yiwuku.com/myService.aspx?jsonp=callbackFunction" />
2. 在客户端写callbackFunction函数的实现
<script type="text/javascript">
function onCustomerLoaded(result, methodName)
{
var html = '<ul>';
for(var i = 0; i < result.length; i++)
{
html += '<li>' + result + '</li>';
}
html += '</ul>';
document.getElementById('divCustomers').innerHTML = html;
}
</script>
3. 页面展示
<div id="divCustomers"></div>
4. 最终Page Code
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head>
<title>Top Customers with Callback</title>
</head>
<body>
<div id="divCustomers"></div>
<script type="text/javascript">
function onCustomerLoaded(result, methodName)
{
var html = '<ul>';
for(var i = 0; i < result.length; i++)
{
html += '<li>' + result + '</li>';
}
html += '</ul>';
document.getElementById('divCustomers').innerHTML = html;
}
</script>
<script type="text/javascript" src="http://www.yiwuku.com/myService.aspx?jsonp=callbackFunction"></script>
</body>
</html>
3) JSONP在JQuery中如何体现的
1. $.getJSON
<script>
$(document).ready(function(){
function(data){
$.each(data.items, function(i,item){
$("<img/>").attr("src", item.media.m).appendTo("#images");
if ( i == 3 ) return false;
});
});
});
</script>
jsoncallback=?,其中?会自动替换为function(data)函数。
2. $.ajax
$.ajax({
dataType: 'jsonp',
data: 'id=10',
jsonp: 'jsonp_callback',
url: 'http://www.yiwuku.com/getdata',
success: function () {
// do stuff
},
});
4) 如何在服务器端实现对JSON支持?
这仅仅需要把服务的JSON数据转换成想要的script tags的形式就可以了,格式可以自已定义,毕竟这是个非官方的协议。
可参考:Implement JSONP in your Asp.net Application
注:Callback仅仅是JSONP的简单实现,可以根据具体需要实现更复杂的功能,比如可以在客户端动态集成更多的变量数据来完成分页功能。
什么是JSONP协议?
JSONP即JSON with Padding。由于同源策略的限制,XmlHttpRequest只允许请求当前源(域名、协议、端口)的资源。如果要进行跨域请求,我们可以通过使用html的script标记来进行跨域请求,并在响应中返回要执行的script代码,其中可以直接使用JSON传递javascript对象。这种跨域的通讯方式称为JSONP。
很明显,JSONP是一种脚本注入(Script Injection)行为,需要特别注意其安全性。
在asp.net中实现简单的JSONP非常简单。我们需要两个页面,分别承担协议的客户端和服务器端角色。
假设我们有两个站点,http://www.baa.com.cn 和 http://www.bitauto.com
我们的客户端页面为 http://www.baa.com.cn/JSONPClient.aspx ;而我们的服务器端页面为http://www.bitauto.com/JSONPServer.aspx 。
首先,我们来做客户端页面:
==========Javascript代码段1:JSONP客户端发送请求的方法=================
function CallJSONPServer(url){ // 调用JSONP服务器,url为请求服务器地址
var oldScript =document.getElementById(url); // 如果页面中注册了调用的服务器,则重新调用
if(oldScript){
oldScript.setAttribute("src",url);
return;
}
var script =document.createElement("script"); // 如果未注册该服务器,则注册并请求之
script.setAttribute("type", "text/javascript");
script.setAttribute("src",url);
script.setAttribute("id", url);
document.appendChild(script);
}
------------------END------------------------
===========Javascript代码段2:JSONP客户端对服务器开放的接口方法=======================
function OnJSONPServerResponse(obj){
alert(obj);
}
------------------END------------------------
===========HTML代码段1:JSONP客户端向用户提供的UI===============
<input type="button" onclick="CallJSONPServer('http://www.bitauto.com/JSONPServer.aspx')" />
------------------END------------------------
至此,JSONP客户端完成,接下来我们做JSONP服务器端页面:
============C#代码段1:应答JSONP客户端请求================
protected void Page_Load(object sender, EventArgs e)
{
Response.DisableKernelCache();
Response.Cache.SetNoStore();
Response.Write("OnJSONPServerResponse('" + DateTime.Now.ToString() + "');");
Response.End();
}
------------------END------------------------
OK,我们现在就完成了,您不妨自己实践一下。