關鍵字:jsonp
jsonp的原理:同源約束限制了js腳本的跨域訪問,但是<script>和<iframe>的src標簽引用的js文件(只要響應正文是符合js語法的文本即可,不一定是js文件),沒有限制。
簡述:
瀏覽器端定義callback函數,名字可以隨意,暫且把它就叫callback,然后把改名字傳給跨域(剛好可以跨域,也可以是同域,即實現了非XMLHttpRequest也可以ajax),
服務器的響應正文,是callback函數的調用,注意整個正文都需要符合js語法,這樣巧妙的實現了跨域。
上代碼,自己寫的demo,在別人的代碼上有改進:
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="WebForm1.aspx.cs" Inherits="WebApplication2.WebForm1" %> <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head runat="server"> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> <title></title> <script type="text/javascript"> var url = "http://www.a.com:8065/Handler1.ashx?c=callback"; //www.a.com本系統目錄的hosts中配置下即可,映射到127.0.0.1 function p(src) { //參數r是避免ie瀏覽器的緩存,在IE中如果短時間請求相同的url,不會從服務器讀取,而是從緩存讀取 var u = src + "&r=" + parseInt((Math.random() * 100000000000000000)); var d = document.createElement("script"); d.setAttribute("type", "text/javascript"); d.src = u; document.body.appendChild(d); } function callback(d) { document.getElementById("e").innerHTML = d; } window.onload = function () { p(url); }; </script> </head> <body> <form id="form1" runat="server"> <div>test <span id="e"></span> <input type="button" value="重新請求" title="重新請求" onclick="p(url)" /> </div> </form> </body> </html>
www.a.com:8066的handler1.aspx.cs的代碼
using System; using System.Collections.Generic; using System.Linq; using System.Web; namespace WebApplication1 { /// <summary> /// Handler1 的摘要說明 /// </summary> public class Handler1 : IHttpHandler { public void ProcessRequest(HttpContext context) { context.Response.ContentType = "application/javascript";//該值不影響結果 var c=context.Request["c"]; context.Response.Write(c + "('" +Guid.NewGuid().ToString()+ "')");//注意傳給callbak函數的參數,是js語法,所以要加引號 } public bool IsReusable { get { return false; } } } }
細節都在注釋中說明了
僅此備忘
ps:不能取代XMLHttpRequest的是,post和head等請求
