1 [WebMethod] 2 public string SayHello(string name) 3 { 4 return "Hello " + name; 5 }
1 $.ajax({ 2 url: "/CommonService.asmx/SayHello", 3 type: "Post", 4 dataType: "json", 5 contentType: "application/json; charset=utf-8", 6 data: "{name:'Varchar32'}", 7 success: function (data) { 8 alert(data.d); 9 }, 10 error: function (data) { 11 //200的響應也有可能被認定爲error,responseText中沒有Message部分 12 alert($.parseJSON(data.responseText).Message); 13 }, 14 complete: function (data) { 15 ;//after success or error 16 } 17 });
type:請求方式,又稱Methodjavascript
dataType:預期返回類型(The type of data that you're expecting back from the server)html
contentType:發送到服務器的數據的編碼類型(When sending data to the server, use this content type)java
data:發送到服務器的數據jquery
1 [WebMethod] 2 public string HelloWorld() 3 { 4 return "Hello World"; 5 }
1 //js的其餘部分略 2 success: function (data) { 3 $(".ajaxresult div:eq(0)").html("返回數據的類型爲:" + typeof(data.d)); 4 $(".ajaxresult div:eq(1)").html("內容爲:" + data.d); 5 }
瀏覽器看到的結果web
另附上採用text格式調用的代碼ajax
1 $.ajax({ 2 url: "/CommonService.asmx/HelloWorld", 3 type: "Post", 4 dataType: "text", 5 data: {}, 6 success: function (data) { 7 $(".ajaxresult div:eq(0)").html("返回數據的類型爲:" + typeof (data)); 8 $(".ajaxresult div:eq(1)").html("內容爲:" + data); 9 } 10 });
1 [WebMethod] 2 public int HelloWorld() 3 { 4 return 1; 5 }
js部分略json
瀏覽器看到的結果跨域
1 [WebMethod] 2 public List<string> HelloWorld() 3 { 4 return new List<string>() { "Frozen_Zhang","Varchar32"}; 5 }
1 //js的其餘部分略 2 success: function (data) { 3 $(".ajaxresult div:eq(0)").html("返回數據的類型爲:" + typeof (data.d)); 4 var str = ""; 5 $.each(data.d, function (index, val) { 6 str += "第" + index + "項:" + val + " ;"; 7 }); 8 str = str.substring(0,str.length - 1); 9 $(".ajaxresult div:eq(1)").html("內容爲:" + str); 10 }
瀏覽器看到的結果數組
1 public class Person 2 { 3 public string Name { get; set; } 4 public bool Gender { get; set; } 5 }
1 [WebMethod] 2 public Person HelloWorld() 3 { 4 return new Person() { 5 Name = "Varchar32", 6 Gender = true 7 }; 8 }
1 //js的其餘部分略 2 success: function (data) { 3 $(".ajaxresult div:eq(0)").html("返回數據的類型爲:" + typeof (data.d)); 4 $(".ajaxresult div:eq(1)").html("內容爲:姓名" + data.d.Name + ",性別" + (data.d.Gender ? "男" : "女")); 5 }
瀏覽器看到的結果瀏覽器
1 [WebMethod] 2 public List<Person> HelloWorld() 3 { 4 return new List<Person>(){ 5 new Person() { 6 Name = "Varchar32", 7 Gender = true 8 }, 9 new Person(){ 10 Name = "Frozen_Zhang", 11 Gender = true 12 } 13 }; 14 }
1 //js的其餘部分略 2 success: function (data) { 3 $(".ajaxresult div:eq(0)").html("返回數據的類型爲:" + typeof (data.d)); 4 var str = ""; 5 $.each(data.d, function (index, val) { 6 str += "第" + index + "項:" + "姓名" + val.Name + ",性別" + (val.Gender ? "男" : "女") + " ;"; 7 }); 8 str = str.substring(0, str.length - 1); 9 $(".ajaxresult div:eq(1)").html("內容爲:" + str); 10 }
瀏覽器看到的結果
1 [WebMethod] 2 public Dictionary<string,string> HelloWorld() 3 { 4 //鍵必須是string類型 5 var dict = new Dictionary<string, string>(); 6 dict.Add("1","Varchar32"); 7 dict.Add("2", "Frozen_Zhang"); 8 return dict; 9 }
1 //js的其餘部分略 2 success: function (data) { 3 $(".ajaxresult div:eq(0)").html("返回數據的類型爲:" + typeof (data.d)); 4 var str = ""; 5 $.each(data.d, function (key, val) { 6 str += "鍵:" + key + ",值:" + val + " ;"; 7 }); 8 str = str.substring(0, str.length - 1); 9 $(".ajaxresult div:eq(1)").html("內容爲:" + str); 10 }
瀏覽器看到的結果
1 [WebMethod] 2 public DataSet HelloWorld() 3 { 4 var ds = new DataSet(); 5 var dt = new DataTable(); 6 dt.Columns.Add("Name"); 7 dt.Columns.Add("Gender"); 8 dt.Rows.Add("Varchar32", true); 9 dt.Rows.Add("Frozen_Zhang", true); 10 ds.Tables.Add(dt); 11 return ds; 12 }
1 //此處採用xml格式調用
$.ajax({ 2 url: "/CommonService.asmx/HelloWorld", 3 type: "Post", 4 dataType: "xml",
7 data: {}, 9 success: function (data) { 10 var str = ""; 11 $.each($.find("Table1", data), function () { 12 str += $(this).find("Name").text() + (Boolean($(this).find("Gender").text()) ? "男" : "女") + ";"; 13 }); 14 15 str = str.substring(0, str.length - 1); 16 $(".ajaxresult div:eq(1)").html("內容爲:" + str); 17 } 18 });
瀏覽器看到的結果
*、用xml格式調用比較簡單,用json格式要引用Microsoft.Web.Preview.dll庫,還要在web.config中添加一大串,比較麻煩
javascript的同源策略(Same-Origin Policy):js不能訪問不在同一域下的頁面內容,所以XmlHttpRequest只能請求在同一源下的資源
但script標籤的src屬性不受同源策略的影響
1 <script type="text/javascript" id="script1"> 2 funccallback = function (data) { 3 alert(data); 4 } 5 </script> 6 <script type="text/javascript" id="script2"> 7 funccallback("Varchar32"); 8 </script>
上面的腳本確定沒問題
如今假設另外一個源url.com下有一js腳本scirpt.js,只有一句
funccallback("Varchar32");
我將script2改爲下面一段帶src屬性的腳本
1 <script type="text/javascript" src="http://www.url.com/scirpt.js"> 2 </script>
也會順利彈窗
隨意改變http://www.url.com/scirpt.js裏給funccallback傳遞的參數,就是說scirpt1中的funccallback接受到了其餘源下的動態數據
$.ajax()就是對這種請求形式進行了封裝,向其餘源的服務器發送一個GET請求,返回一個指定格式的數據
這種格式就是JSONP格式:回調函數名(json格式的動態數據)
1 public void ProcessRequest(HttpContext context) 2 { 3 string callback = context.Request.QueryString["callback"]; 4 var name = context.Request.QueryString["name"]; 5 string json = "{\"name\":\"" + name + "\",\"gender\":\"" + "男" + "\"}"; 6 //JSONP格式:回調函數名(json格式參數) 7 //括號後不要加分號 8 string result = callback + "(" + json + ")"; 9 context.Response.ContentType = "application/json"; 10 context.Response.Write(result); 11 }
1 //回調函數funccallback,回調函數的定義不要放在 $(function () { });裏 2 function funccallback(data) { 3 alert("in callback" + ":" + data.name + ", 性別" + data.gender); 4 } 5 6 $.ajax({ 7 url: "http://localhost:12500/handler1.ashx?callback=?", 8 dataType: "jsonp", 9 //jsonpCallback: "funccallback", 10 //說明:一、未指定jsonpCallback項則會產生一個隨機回調函數名,是由ajax方法隨機生成,而不是服務器;二、jsonpCallback項和url的callback參數不可同時指定(callback參數指定爲'?'除外);三、隨機函數名就意味着成功返回後只會執行success,指定回調函數反而會顯得多餘 11 data: { name: "Varchar32" }, 12 //執行順序是success在回調函數以後 13 success: function (data) { 14 //data,同回調函數中的data,就是在服務器端爲回調函數傳遞的json格式參數 15 alert("in success" + ":" + data.name + ", 性別" + data.gender); 16 } 17 });
腳本執行結果爲瀏覽器彈出確認框:‘in success:Varchar32, 性別男’
firefox瀏覽器中看到的響應
1 [WebMethod] 2 public void GetGenderByName(string callback, string name) 3 { 4 var json = "{\"name\":\"" + name + "\",\"gender\":\"" + "男" + "\"}"; 5 string result = callback + "(" + json + ")"; 6 HttpContext.Current.Response.ContentType = "application/json"; 7 HttpContext.Current.Response.Write(result); 8 HttpContext.Current.Response.End(); 9 }
1 //回調函數funccallback,回調函數的定義不要放在 $(function () { });裏 2 function funccallback(data) { 3 alert("in callback" + ":" + data.name + ", 性別" + data.gender); 4 } 5 6 $.ajax({ 7 url: "http://localhost:12500/CommonService.asmx/GetGenderByName?callback=?", 8 dataType: "jsonp", 9 //jsonpCallback: "funccallback", 10 data: { name: "Varchar32" }, 11 success: function (data) { 12 alert("in success" + ":" + data.name + ", 性別" + data.gender); 13 } 14 });
1 $.getJSON("http://localhost:12500/CommonService.asmx/GetGenderByName?name=Varchar32&callback=?", 2 function (data) { 3 alert("in success" + ":" + data.name + ", 性別" + data.gender); 4 } 5 );
1 public void ProcessRequest(HttpContext context) 2 { 3 string callback = context.Request.QueryString["callback"]; 4 var name = context.Request.QueryString["name"]; 5 6 var person = new Person() 7 { 8 Name = name, 9 Gender = true 10 }; 11 12 DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(Person)); 13 MemoryStream ms = new MemoryStream(); 14 ser.WriteObject(ms, person); 15 string jsonString = Encoding.UTF8.GetString(ms.ToArray()); 16 ms.Close(); 17 18 string json = jsonString; 19 20 //JSONP格式:回調函數名(json格式參數) 21 //括號後不要加分號 22 string result = callback + "(" + json + ")"; 23 context.Response.ContentType = "application/json"; 24 context.Response.Write(result); 25 }
1、webservice定義了幾個方同名的法時,ajax請求會被同名方法中的最後一個響應,而不是根據參數自動匹配
2、Method use ‘Get’,返回xml or text,要在Web.config中添加節點
<webServices><protocols><add name= "HttpGet"/></protocols></webServices>
3、Method use ‘Get’,返回json,要給Webservice的方法添加UseHttpGet特性
[ScriptMethod(UseHttpGet=true)]
4、dataType並非服務器返回數據的類型(格式),just expecting。看下面的幾種請求方式
第一種:通常方式
1 $.ajax({ 2 url: "/CommonService.asmx/SayHello", 3 type: "Post", 4 dataType: "json", 5 contentType: "application/json; charset=utf-8", 6 data: "{ name: 'Varchar32' }", 7 success: function (data) { 8 alert(data.d); 9 }, 10 error: function (data) { 11 alert(data); 12 } 13 });
結果彈出確認框‘Hello Varchar32’,從firefox看到的結果
第二種:省略dataType項,代碼略,結果和第一種同樣,彈出確認框‘Hello Varchar32’
第三種:給dataType指定爲‘text’,代碼略,彈出確認框‘undefined’,但返回結果從firefox看和上面兩種第二種請求格式同樣
第四種:給dataType指定爲‘xml’,代碼略,結果執行了error方法,但返回結果從firefox看和以上幾種方式同樣(200的響應被認定爲了error)
爲何第二種狀況不會報錯,第三種明明返回了json格式,但data.d爲何是undefined呢,而第四種請求會被認定爲error
1)認真從firefxo中觀察請求頭和響應頭會發現,響應頭的content-Type始終是‘application/json; charset=utf-8’
2)請求頭的Accept項有所不一樣,分別是
常規格式:
省略dataType項:
給dataType指定爲‘text’:
給dataType指定爲‘xml’
3)從jquery官網上找到$.ajax()的選項content-Type定義中的這麼一句
If you explicitly pass in a content-type to $.ajax()
, then it is always sent to the server (even if no data is sent)
意思差很少就是:若是指定了‘content-Type’,無論有沒有數據,始終發送到服務器
若是僅僅是提交的數據的類型(格式),爲何沒數據還要發送到服務器呢
4)修改success方法
1 success: function (data) { 2 alert(typeof(data)); //alert data 的類型 3 alert(data.d); 4 },
結果分別是:object、object、string、不執行success
結論:(假設成功返回,狀態碼200)
content-Type同時是提交數據和返回數據的類型(格式)。即若指定爲‘application/json; charset=utf-8’,則返回類型必定爲‘json’,此時dataType可省略;未指定則默認返回的是xml格式的數據
dataType爲預期(expecting)的返回格式(格式比類型更恰當),若實際返回格式與預期格式相同 或 預期格式在js中對應的數據類型爲String(text、html格式對應的爲String,json、xml對應Object),則執行succes,不然被認定爲error。第四種請求方式,返回格式爲json,預期格式爲xml,兩種格式不一樣 且 預期格式在js中對應的類型爲Object,雖然200,依然被認定爲error
success方法獲取到的返回數據data的類型爲預期返回格式在js中對應的類型(Object或String),第三種請求方式,data的類型爲String,內容爲‘{"d":"Hello World"}’,對String調用.d,固然是undefined,假設有一句‘alert($.parseJSON(data).d);’,此句會獲得想要的結果
dataType做用:一、判斷是success仍是error;二、success方法接受到的數據data的類型
5、content-Type的幾種可選類型: text:「text/plain「; xml:「application/xml「; json:「application/json「; html:「text/html」; script:"application/x-javascript"
6、採用json格式爲何要‘.d’,json格式是一Ojbect,微軟框架默認的是{"d":"後臺返回的數據"},d屬性的值纔是後臺返回的數據