標籤:blog http java os io 檔案 資料 ar
一、jsonp
其實我本以為jsonp能夠做到利用AJAX任意訪問別人的程式碼,但是我發現實際並不是我想象的那樣,因為jsonp要改動伺服器端的代碼。別人的伺服器端代碼怎麼改啊?除非別人願意,否則你還是不能用AJAX擷取別人的資料。
Ajax直接請求普通檔案存在跨域無許可權訪問的問題,甭管你是靜態頁面、動態網頁、web服務、WCF,只要是跨域請求,一律不準;其實jsonp的原理就是遠程執行js。
<script type="text/javascript" src="遠程js檔案"></script>
樣本-伺服器端代碼:
namespace AJAXDomain.Controllers{ public class HomeController : Controller { public ActionResult Index() { return View(); } public ActionResult GetPerson() { Person p = new Person(); p.Id = 1; p.Name = "劉備"; p.Age = 24; JavaScriptSerializer jss = new JavaScriptSerializer(); string json = jss.Serialize(p); //序列化成JSON string callback = Request["callback"]; //拼接有點奇葩 string call = callback + "(" + json + ")"; //callback拼接上括弧和繼承的json return Content(call); } } public class Person { public int Id { get; set; } public string Name { get; set; } public int Age { get; set; } }}
修改hosts表:
127.0.0.1 www.baidu.com
前台頁面代碼:
<html><head> <title>Index</title> <script src="jquery-1.7.1.min.js"></script> <script type="text/javascript"> $(function () { //下面這段是直接擷取本網域名稱下的json,但是不支援跨域 //$.ajax({ // url: "http://www.baidu.com:8881/Home/GetPerson", // type: "get", // dataType: "text", // success: function (response) { // var p = getObject(response); // $("#div1").text("姓名:" + p.Name + "年齡:" + p.Age); // } //})
//跨域AJAX(jsonp) $.ajax({ type: "get", async: false, url: "http://www.baidu.com:8881/Home/GetPerson", dataType: "jsonp", jsonp: "callback", //傳遞給請求處理常式或頁面的,用以獲得jsonp回呼函數名的參數名(一般預設為:callback) //jsonpCallback:"?", //自訂的jsonp回呼函數名稱,預設為jQuery自動產生的隨機函數名,也可以寫"?",jQuery會自動為你處理資料 success: function(p){ //var p = getObject(json); //這裡要注意下,jsonp返回之後jQuery會直接轉成js對象,不用再轉了。 $("#div1").text("姓名:" + p.Name + "年齡:" + p.Age); alert(p.Name); }, error: function(){ alert(‘跨域失敗!‘); } }) }) function getObject(str) { return eval("(" + str + ")"); } </script></head><body> <div> 測試跨域: </div> <div id="div1"> </div></body></html>
頁面輸出的效果如下:
二、代理訪問
代理訪問實際上就是通過後端代碼如.NET、JAVA、PHP擷取到資料,再返回。這個沒什麼好說的,你搞個WebClient下載頁面字串,再發給前台而已。
三、iframe方法
這個適合約一主網域名稱的二級域及主網域名稱之間的相互訪問。比如:www.a.com和blog.a.com之間的ajax互動,在兩個域下的頁面都加上document.domain = "a.com"就可以了。
其次,是不同主網域名稱之間的iframe跨域:
namespace MVC___學習測試.Controllers{ public class HomeController : Controller { public ActionResult Index() { return View(); } //類比跨域頁,假設這個是不同網域名稱的頁 public ActionResult GetData() { return View(); } public ActionResult GetPerson() { Person p = new Person(); p.Id = 1; p.Name = "劉備"; p.Age = 24; return Json(p, JsonRequestBehavior.AllowGet); } } public class Person { public int Id { get; set; } public string Name { get; set; } public int Age { get; set; } }}
GetData視圖:
<html><head> <title>同域頁</title> <script type="text/javascript" src="/Scripts/jquery-1.4.1.min.js"></script> <script type="text/javascript"> function getObject(str) { return eval("(" + str + ")"); } $(function() { //下面這段是直接擷取本網域名稱下的json $.ajax({ url: "http://localhost:5908/Home/GetPerson", type: "get", dataType: "text", success: function(response) { var p = getObject(response); parent.SonRun(p); //通過parent擷取父視窗的變數、函數等,將傳回值傳過去,實際上不過是對windows.parent對象的理解。 } }) }) </script></head><body></body></html>
Index視圖:
<html><head> <title>IFrame跨域測試</title> <script type="text/javascript" src="/Scripts/jquery-1.4.1.min.js"></script> <script type="text/javascript"> function SonRun(p) { $("#div1").text(p.Id + p.Name + p.Age); } </script></head><body><iframe id="if1" width="0" height="0" src="http://localhost:5908/Home/GetData"></iframe> <div id="div1"></div></body></html>
開啟路徑:http://localhost:5908/
輸出如下: