在web開發中,如果你要在不同域下進行數據異步請求,會出現一個No ‘Access-Control-Allow-Origin’ header is present on the requested resource.”的錯誤提示。
該提示信息說明,跨域請求是違反了“同源策略”的。
但是在開發中又難免會遇到跨域請求的需求,所以前輩們也是留下了跨域請求數據的方法jsonp跨域請求。
我們以最為典型的Jquery做例子,后台用的asp.net mvc。
我們先構造一個action的返回對象,用於返回jsonp數據
#region JsonResult public class JsonpResult<T> : ActionResult { public T Obj { get; set; } public string CallbackName { get; set; } public JsonpResult(T obj, string callback) { this.Obj = obj; this.CallbackName = callback; } public override void ExecuteResult(ControllerContext context) { var js = new System.Web.Script.Serialization.JavaScriptSerializer(); var jsonp = this.CallbackName + "(" + js.Serialize(this.Obj) + ")"; context.HttpContext.Response.ContentType = "application/json"; context.HttpContext.Response.Write(jsonp); } } #endregion
寫一個供前台調用的action ,callback參數是必須的一個參數
public ActionResult AjaxJsonp(string s, string f,string callback) { string result=s+'-'+f; return new JsonpResult<object>(new { result = result }, callback); }
然后我們在前台用Ajax跨域調用該方法(如果是在本地測試,在不同的端口號下即可)
$.ajax({ type: "GET", url: "AjaxJsonp?callback=?", data: { s: '',f:''}, cache: false, error: function () { alert("程序出錯,請聯系管理員."); }, dataType: "jsonp", jsonp: 'callback', success: function (result) { if (result) { //返回對象處理 } } });
原理:
類似於使用js創建一個script元素,引用的地址就是我們請求的地址。
既然引用了該地址,而我們的地址輸出的是:
callback(data);
這就相當於執行了一個函數:callback,並把data傳入了這個函數,所以我們就拿到了data;
介紹Ajax jsonp跨域請求的參數說明
- type:請求的類型(get/post),這里需要注意的是,跨域請求只能是Get方式請求,這是因為限制於實現跨域的原理,但你會發現,將type寫為post同樣能執行,這是為什么呢?
在仔細查看監控的請求方式,其實還是GET方式,這就說明Jquery在內部已經做了處理,所以跨域請求只能是get請求,請求數據量是很有限的。 - url:url后面的callback=?是必須的,Jquery會將?號生成一個隨機的名字,用於回調
- data:傳遞的參數
- cache:是否開啟緩存,如果請求的數據是不變的,那么可以開啟緩存提高效率
- dataType:一定是jsonp
- jsonp:callback名一般使用默認callback,可自行修改
- error:請求出錯時執行
- success:請求成功回調並返回結果數據