1: 跨域的理解
說起跨域就必須要提同源策略,瀏覽器問了安全,制定了同源策略,即同協(xié)議、同域名、同端口號,若其中有一點存在不同就會違背同源策略,導致無法獲得數(shù)據(jù)。(若是非同源的,其實瀏覽器會向服務器發(fā)起請求,但是會拒絕接收服務器返回的數(shù)據(jù))
舉例:在本地存在2個項目,web1和web2,同時運行在兩個端口3000和3001,當web1向web2發(fā)起請求http://localhost:3001/ajax/deal時,就會造成跨域問題。
2:jsonp
既然這么容易跨域,那就得想解決方法。我們發(fā)現(xiàn),當在web1中,使用
<script src="http://localhost:30001/test.js"></script>
發(fā)現(xiàn)script標簽并沒有同源的限制,我們可以正常獲得test.js。jsonp就是利用script標簽的這個特點,在本地創(chuàng)建一個回調函數(shù),然后在遠程服務上調用這個函數(shù),并且將需要的數(shù)據(jù)拼接成json數(shù)據(jù)的形式作為參數(shù)傳遞,完成回調。
其實jsonp的實質就是將json數(shù)據(jù)填充進回調函數(shù),jsonp = json+padding。
舉例:web2中服務端的一段代碼
public class MyService : IHttpHandler
{
public void ProcessRequest(HttpContext context)
{
//獲取回調函數(shù)名
string callback = context.Request.QueryString["callback"];
//json數(shù)據(jù)
string json = "{\"name\":\"chopper\",\"sex\":\"man\"}";
context.Response.ContentType = "application/json";
//輸出:回調函數(shù)名(json數(shù)據(jù))
context.Response.Write(callback + "(" + json + ")");
}
public bool IsReusable
{
get
{
return false;
}
}
}
web1中頁面中代碼
<script type="text/javascript">
function addScriptTag(src){
var script = document.createElement('script');
script.setAttribute("type","text/javascript");
script.src = src;
document.body.appendChild(script);
}
window.onload = function(){
//調用遠程服務
addScriptTag("http://localhost:20002/MyService.ashx?callback=person");
}
//回調函數(shù)person
function person(data) {
alert(data.name + " is a " + data.sex);
}
</script>
3: 由于script的原理 所以jsonp只適用于get方法請求。
4:強烈推薦深入淺出jsonp, 很贊