簡(jiǎn)單來(lái)說(shuō)Ajax是一個(gè)無(wú)需重新加載整個(gè)網(wǎng)頁(yè)的情況下,可以更新局部頁(yè)面或數據的技術(shù)(異步的發(fā)送接收數據,不會(huì )干擾當前頁(yè)面)。
Ajax使瀏覽器和服務(wù)器之間多了一個(gè)Ajax引擎作為中間層。通過(guò)Ajax請求服務(wù)器時(shí),Ajax會(huì )自行判斷哪些數據是需要提交到服務(wù)器,哪些不需要。只有確定需要從服務(wù)器讀取新數據時(shí),Ajax引擎才會(huì )向服務(wù)器提交請求。

不需要提交整個(gè)頁(yè)面就可以更新數據。
與服務(wù)器異步通信。
Ajax請求不能后退,瀏覽器沒(méi)有歷史記錄。
Ajax請求的頁(yè)面不能加入到收藏夾。
JQuery 對 Ajax 做了大量的封裝,不需要去考慮瀏覽器兼容性,使用起來(lái)也較為方便。
jquery對Ajax一共有三層封裝。
最底層:$.ajax()。
第二層:.load()、$.get()和$.post()。
最高層: $.getScript()和$.getJSON()方法。
$.Ajax()是所有Ajax方法中最底層的方法,其他的都是基于$.Ajax()方法的封裝,該方法只有一個(gè)參數-JQueryAjaxSettings(功能鍵值對)。
$.Ajax參數JQueryAjaxSettings介紹:
| 參數 | 類(lèi)型 | 說(shuō)明 |
|---|---|---|
| url | String | 請求的地址 |
| type | String | 請求方式:POST 或 GET,默認 GET |
| timeout | Number | 設置請求超時(shí)的時(shí)間(毫秒) |
| data | Object或String | 發(fā)送到服務(wù)器的數據,鍵值對或字符串 |
| dataType | String | 從服務(wù)器返回的數據類(lèi)型,比如 html、xml、json 等 |
| beforeSend | Function | 發(fā)送請求前可修改 XMLHttpRequest 對象的函數 |
| complete | Function | 請求完成后調用的回調函數 |
| success | Function | 請求成功后調用的回調函數,先執行success再執行complete |
| error | Function | 請求失敗時(shí)調用的回調函數,先執行error再執行complete |
| global | Boolean | 默認為 true,表示是否觸發(fā)全局 Ajax |
| cache | Boolean | 設置瀏覽器緩存響應,默認為 true。如果 dataType類(lèi)型為 script 或 jsonp 則為 false。 |
| content | DOM | 指定某個(gè)元素為與這個(gè)請求相關(guān)的所有回調函數的上下文。 |
| contentType | String | 指 定 請 求 內 容 的 類(lèi) 型 。 默 認 為application/x-www-form-urlencoded。 |
| async | Boolean | 是否異步處理。默認為 true,false 為同步處理 |
| processData | Boolean | 默認為 true,數據被處理為 URL 編碼格式。如果為 false,則阻止將傳入的數據處理為 URL 編碼的格式。 |
| dataFilter | Function | 用來(lái)篩選響應數據的回調函數。 |
| ifModified | Boolean | 默認為 false,不進(jìn)行頭檢測。如果為true,進(jìn)行頭檢測,當相應內容與上次請求改變時(shí),請求被認為是成功的。 |
| jsonp | String | 指定一個(gè)查詢(xún)參數名稱(chēng)來(lái)覆蓋默認的 jsonp 回調參數名 callback。 |
| username | String | 在 HTTP 認證請求中使用的用戶(hù)名 |
| password | String | 在 HTTP 認證請求中使用的密碼 |
| scriptCharset | String | 當遠程和本地內容使用不同的字符集時(shí),用來(lái)設置 script 和 jsonp 請求所使用的字符集。 |
| xhr | Function | 用來(lái)提供 XHR 實(shí)例自定義實(shí)現的回調函數 |
| traditional | Boolean | 默認為 false,不使用傳統風(fēng)格的參數序列化。如為 true,則使用 |
代碼示例:
$('button').click(function(){ $.ajax( { type:'post', url:'test', data:{ url:'hello', }, dataType:'json', success:function(data,stutas,xhr){ alert(data); }, error:function(xhr, textStatus, data)){ alert(data); }, complete:function(xhr,textStatus){ alert(textStatus); } } )});$.Ajax的回調函數介紹:
success
Function( Anything data, String textStatus, jqXHR jqXHR )
請求成功后執行的回調函數。
| 參數 | 類(lèi)型 | 說(shuō)明 |
|---|---|---|
| data | anything | 從服務(wù)器返回的數據,并根據dataType參數類(lèi)型處理后的數據(默認是json) |
| textStatus | string | 描述狀態(tài)的字符串 |
| jqxhr | jqXHR | XMLHTTPRequest對象 |
error
Function( jqXHR jqXHR, String textStatus, String errorThrown )
請求失敗是執行的回調函數
| 參數 | 類(lèi)型 | 說(shuō)明 |
|---|---|---|
| errorThrown | string | HTTP狀態(tài)的文本部分 |
| textStatus | string | 描述錯誤信息的字符串 |
| jqxhr | jqXHR | 描述發(fā)生錯誤類(lèi)型的一個(gè)字符串 和 捕獲的異常對象 |
complete
Function( jqXHR jqXHR, String textStatus )
請求完成后執行的回調函數,不管是成功還是失敗都執行。
| 參數 | 類(lèi)型 | 說(shuō)明 |
|---|---|---|
| errorThrown | string | HTTP狀態(tài)的文本部分 |
| textStatus | string | 描述請求狀態(tài)的字符串 |
| jqxhr | jqXHR | XMLHTTPRequest對象 |
從服務(wù)器獲取數據并且將返回的HTML代碼插入至匹配的元素中。
$('Element').load(url,data,success(responseText,textStatus,XMLHttpRequest))| 參數 | 類(lèi)型 | 說(shuō)明 |
|---|---|---|
| url | string | 必須 請求地址 |
| data | Json或者string | 可選 請求數據 如果是json該load方法是post請求,默認是get請求 |
| success | function | 當請求成功后執行的回調函數 |
| responseText | string | 獲得字符串形式的響應數據 |
| textStatus | string | 文本方式返回HTTP狀態(tài)碼 |
| XMLHttpRequest | Object | xhr對象,有多種屬性 |
.load()一般在獲取靜態(tài)資源時(shí)調用,$.get()和$.post()方法在需要和服務(wù)器交互數據時(shí)調用。
$.get() 方法通過(guò) HTTP GET 請求載入信息。
這是$.ajax GET請求的簡(jiǎn)寫(xiě)方式。請求成功時(shí)可調用回調函數。
$.get(url,data,success(response,status,xhr),dataType)使用$.get()從服務(wù)端獲取數據-代碼示例
定義model
public class PersonViewModel{ public int PersonID { get; set; } public string Name { get; set; } public string PhoneNum { get; set; } public bool IsMarried{get;set;} }定義Controller Action
public class MyAjaxController : Controller { public JsonResult PersonList() { IList<PersonViewModel> persons = new List<PersonViewModel>(); for (int i = 0; i < 10; i++) { persons.Add(new PersonViewModel() { Email = "email" + i, Name = "name", IsMarried = false, PhoneNum = "1234" + i, Home = CityEnum.BJ, Height = i }); } return Json(persons,JsonRequestBehavior.AllowGet); } }定義View
$.get('@Url.Action("PersonList", "MyAjax")',function (result) { $.each(result, function (index, person) { $('#myDiv').append('<p>Id: ' + person.PersonID + '</p>' + '<p>Name: ' + person.Name + '</p>'); }); });//在Jquery1.5版本后,新增了一些事件,可以更好的處理不同結果。$.get('@Url.Action("PersonList", "MyAjax")') .done(function (data) { $.each(data, function (index, person) { $('#myDiv').append('<p>Id: ' + person.PersonID + '</p>' + '<p>Id: ' + person.Name + '</p>'); }); }) .fail(function (data) { alert(data); });$.post() 方法通過(guò) HTTP POST 請求從服務(wù)器載入數據。
$.post(url,data,success(data, textStatus, jqXHR),dataType)使用$.post()方法向服務(wù)端發(fā)送數據-代碼示例
定義一個(gè)Action
[HttpPost]public JsonResult ToPersonList(IEnumerable<PersonViewModel> persons){ if (persons != null) return Json(true); else return Json(false);}定義一個(gè)View
<script>var results = { persons : [{ "PersonID": "1", "Name": "Manas" }, { "PersonID": "2", "Name": "Tester" }] };$.post('@Url.Action("ToPersonList","MyAjax")',results, function (data) { alert(data) });; //同樣也可以使用Jquery1.5版本的新的事件$.post('@Url.Action("ToPersonList","MyAjax")', results) .done(function (data) { alert(data); }) .fail(function (data) { alert(data); }) .always(function (data) { alert(data); })</script>$.get() $.post()方法都是四個(gè)參數,前面三個(gè)參數和$.load()一樣,最后一個(gè)參數dataType:服務(wù)器返回的數據格式:xml、html、script、json、jsonp和text。只有第一個(gè)參數是必須的,其他都可以為空。
$.get() $.post()都是$.ajax()的一個(gè)簡(jiǎn)寫(xiě)封裝,都是只能回調success狀態(tài),error,和complete不能被回調。但是在jquery1.5版本上,新加了jqXHR.done() (表示成功), jqXHR.fail() (表示錯誤), 和 jqXHR.always() 事件,可以實(shí)現不同狀態(tài)的回調。
如果我們有一個(gè)復雜的表單,一個(gè)一個(gè)獲取表單數據是一個(gè)很瑣碎的事。jquery提供了一個(gè)表單的序列化方法serialize(),會(huì )智能的獲取指定表單內的所有元素(包括單選框,復選框,下拉列表等)把表單內容序列化為字符串。此外serializeArray()方法可以把數據整合為鍵值對的json對象。
如果我們需要多次調用$.ajax方法,并且很多參數都相同,可以使用$.ajaxSetup()方法,它會(huì )把一些公共的參數預先設置好,不用每次都設置。
$('form input[type=button]').click(function () { $.ajaxSetup({ type : 'POST', url : 'test', data : $('form').serialize() }); $.ajax({ success : function (response, status, xhr) { alert(response); }); });在使用 data 屬性傳遞數據的時(shí)候,如果是以對象形式傳遞鍵值對,可以使用$.param()方法將對象轉換為字符串鍵值對格式。
(主要是針對無(wú)法直接使用表單序列化方法.serialize(),且傳遞參數為對象的情況)
Asp.Net MVC中包含了一組Ajax輔助方法??梢杂脕?lái)創(chuàng )建異步執行的表單和指向控制器操作的異步鏈接。當使用這個(gè)輔助方法時(shí),不用編寫(xiě)任何腳本代碼來(lái)實(shí)現程序的異步。該輔助方法依賴(lài)于非侵入式MVC的jquery擴展。如果使用這些輔助方法時(shí),需要引入腳本jquery.unbotrusive-ajax.js
(可以在NuGet中獲得)
Asp.Net MVC中的分部頁(yè)面可以是partialPage也可以是含有布局(layout)的完整頁(yè)面。只是在return的時(shí)候返回類(lèi)型是PartialView。
絕大部分情況下,部分頁(yè)面的請求和完整頁(yè)面的請求是一樣的流程-請求被路由到指定控制器,控制器執行特定的業(yè)務(wù)邏輯,返回給對應的試圖。 我們可以在控制器中使用Request.IsAjax來(lái)區別是否是ajax請求,是否是要返回分部試圖,還是完整試圖。分部試圖(return PartialView)是render和返回了該頁(yè)面的html。但是完整試圖(return View)是返回了包括頁(yè)面資源(css,js)和布局的所有html。
異步加載一個(gè)分布頁(yè)面
定義一個(gè)ViewModel
//Model[Bind(Exclude = "PersonID")]public class PersonViewModel{ [ScaffoldColumn(false)] public int PersonID { get; set; } [Display(Name = "姓名")] [Required(ErrorMessage = "不能為空")] public string Name { get; set; } [Display(Name = "手機號")] [Required(ErrorMessage = "不能為空")] [DataType(DataType.PhoneNumber)] public string PhoneNum { get; set; } public bool IsMarried{get;set;}}定義主頁(yè)面View
//Main View:@{ ViewBag.Title = "主頁(yè)面";}<h2>主頁(yè)面</h2><p>列表詳細信息</p><div id="partialDiv"></div><script> $('#partialDiv').load('@Url.Action("ListPage", "MyAjax")')</script>定義分部頁(yè)面View
//分部頁(yè)面@{ ViewBag.Title = "ListPage";}@model IList<WebApp.Models.PersonViewModel><h2>分布頁(yè)</h2><table class="table table-striped"> <thead> @{ WebApp.Models.PersonViewModel p = null;} <tr> <th>@Html.LabelFor(m => @p.Email)</th> <th>@Html.LabelFor(m => @p.Name)</th> <th>@Html.LabelFor(m => @p.Home)</th> <th>@Html.LabelFor(m => @p.IsMarried)</th> <th>@Html.LabelFor(m => @p.Height)</th> <th>@Html.LabelFor(m => @p.PhoneNum)</th> @*也可以使用DisplayNameFor來(lái)顯示表頭*@ @*<th>@Html.DisplayNameFor(m => Model[0].Email)</th> <th>@Html.DisplayNameFor(m => Model[0].Name)</th> <th>@Html.DisplayNameFor(m => Model[0].IsMarried)</th> <th>@Html.DisplayNameFor(m => Model[0].Height)</th> <th>@Html.DisplayNameFor(m => Model[0].PhoneNum)</th>*@ </tr> </thead> <tbody> @foreach (var item in Model) { <tr> <td>@item.Email</td> <td>@item.Name</td> <td>@item.Home</td> <td>@item.IsMarried</td> <td>@item.Height</td> <td>@item.PhoneNum</td> </tr> } </tbody></table>定義一個(gè)Action
//Controller public class MyAjaxController : Controller { //主頁(yè)面public ActionResult MainPage() { return View(); } //分部頁(yè)面public ActionResult ListPage() { IList<PersonViewModel> persons = new List<PersonViewModel>(); for (int i = 0; i < 10; i++) { persons.Add(new PersonViewModel() { Email = "email" + i, Name = "name", IsMarried = false, PhoneNum = "1234" + i, Home = CityEnum.BJ, Height = i }); } if (Request.IsAjaxRequest()) { return PartialView(persons); } return View(persons); } }當請求主頁(yè)面的時(shí)候,會(huì )把分布頁(yè)面異步加載到主頁(yè)面的<div id="partialDiv"></div>里
Ajax.ActionLink()輔助方法,可以異步請求加載頁(yè)面。
//Main view 主頁(yè)面@{ ViewBag.Title = "MainPage";}<h2>主頁(yè)面</h2><p>列表詳細信息</p>@Ajax.ActionLink("加載詳細列表", "ListPage", new AjaxOptions { UpdateTargetId = "partialDiv", InsertionMode = InsertionMode.Replace, HttpMethod = "Get" })<div id="partialDiv"></div>Asp.Net MVC 提供了多個(gè)AjaxOptions的屬性,方法給我們使用,免去了不少js代碼。
如
| 名稱(chēng) | 說(shuō)明 |
|---|---|
| Confirm | 獲取或設置在提交請求之前顯示在確認窗口中的消息。 |
| HttpMethod | 獲取或設置 HTTP 請求方法(“Get”或“Post”)。 |
| InsertionModel | 獲取或設置指定如何將響應插入目標 DOM 元素的模式。插入模式(“InsertAfter”、“InsertBefore”或“Replace”)。 默認值為“Replace”。 |
| LoadingElementDuration | 獲取或設置一個(gè)值(以毫秒為單位),該值控制在顯示或隱藏加載元素時(shí)的動(dòng)畫(huà)持續時(shí)間。 |
| LoadingElementId | 獲取或設置在加載 Ajax 函數時(shí)要顯示的 HTML 元素的 id 特性。 |
| OnBegin | 獲取或設置要在更新頁(yè)面之前立即調用的 JavaScript 函數的名稱(chēng) |
| OnComplete | 獲取或設置在實(shí)例化響應數據之后但在更新頁(yè)面之前,要調用的 JavaScript 函數。 |
| OnFailure | 獲取或設置在頁(yè)面更新失敗時(shí)要調用的 JavaScript 函數。 |
| OnSuccess | 獲取或設置在成功更新頁(yè)面之后要調用的 JavaScript 函數。 |
| UpdateTargetId | 獲取或設置要使用服務(wù)器響應來(lái)更新的 DOM 元素的 ID。 |
| Url | 獲取或設置要向其發(fā)送請求的 URL。 |
當我們使用jquery的ajax提交表單時(shí),需要在click事件中添加e.preventDefault()或者把<input type="submit" value="提交" />改為<input type="button" value="提交" />。否則會(huì )刷新頁(yè)面。如下代碼所示,
<form class="form-horizontal" role="form" method="post" id="myform"> <div> <label for="i1">第一</label> <input type="text" name="i1" id="i1" /> </div> <div> <label for="i2">第二</label> <input type="text" name="i2" id="i2" /> </div> <div> <label for="i3">第三</label> <input type="text" name="i3" id="i3" /> </div> //或者使用<input type="button" value="提交" />,不必再阻止事件的傳遞了。<input type="submit" value="提交" /></form><script> $("input[type=submit]").click(function (e) { e.preventDefault();//阻止事件傳遞$.post("@Url.Action("CheckNameByAjax")", $("#myform").serialize(), function (result) { alert(result); }); });</script>Asp.Net MVC提供了Ajax的表單輔助方法,可以更簡(jiǎn)單快速的實(shí)現表單的ajax提交。
@using (Ajax.BeginForm("AjaxForm", "MyAjax", new AjaxOptions { HttpMethod = "Post", OnComplete = "foo", OnSuccess = "succ", OnFailure = "fail" }, new { role = "form" })){ <div> <label for="i1">第一</label> <input type="text" name="i1" id="i1" /> </div> <div> <label for="i2">第二</label> <input type="text" name="i2" id="i2" /> </div> <div> <label for="i3">第三</label> <input type="text" name="i3" id="i3" /> </div> <input type="submit" value="提交" />}在注冊有時(shí)需要保證用戶(hù)名或者郵箱唯一或者是否合法,這個(gè)驗證又必須放在服務(wù)端完成??梢允褂胊jax異步請求,在用戶(hù)添加完用戶(hù)名或者郵箱的時(shí)候立即在服務(wù)端驗證并告知用戶(hù)結果,而不用填完整個(gè)表單,再去驗證唯一合法性。
定義一個(gè)ViewModel
//Model[Bind(Exclude = "PersonID")]public class PersonViewModel{ [ScaffoldColumn(false)] public int PersonID { get; set; } [Display(Name = "姓名")] [Required(ErrorMessage = "不能為空")] public string Name { get; set; } [Display(Name = "手機號")] [Required(ErrorMessage = "不能為空")] [DataType(DataType.PhoneNumber)] public string PhoneNum { get; set; }}定義試圖View
//view@model NameSpace.PersonViewModel<form class="form-horizontal" role="form" method="post" id="myform"> <div> <div class="form-group"> @Html.LabelFor(m => m.Name, new { @class = "control-label col-md-3" }) <div class="col-md-9"> @Html.TextBoxFor(m => m.Name, new { @class = "form-control" }) @Html.ValidationMessageFor(m => m.Name, "", new { @class = "text-danger" }) </div> </div> <div> <input type="submit" value="提交" class="btn btn-success" id="sure" /> </div> </div></form><script> $("#Name").change(function () { $.ajax({ url: "@Url.Action("CheckUserName")", type: "post", data: { Name: $("#Name").val() }, dataType: "JSON", success: function (response, stutas, xhr) { alert(response+status + xhr.statusText); }, error: function (xhr, stutas, response) { alert(response + status + xhr.statusText); }, complete: function (data) { alert(data.status+data); }, }); }); </script>定義一個(gè)Action校驗用戶(hù)名的唯一和合法性
[HttpPost]//參數一定要和ViewModel的屬性名稱(chēng)一致public JsonResult CheckUserName(string Name){ bool result = true; if (Name == "admin") { result = false; } return Json(result);}至此我們實(shí)現了Ajax的用戶(hù)名唯一性和合法性的校驗。但是 Asp.Net MVC 提供了一個(gè)更簡(jiǎn)單的方法,可以用更少的代碼實(shí)現一樣的功能
在屬性上添加[Remote("MethodName", "ControllerName")]特性
該特性允許客戶(hù)端調用服務(wù)端的方法。
修改Model
[Bind(Exclude = "PersonID")] public class PersonViewModel{ [ScaffoldColumn(false)] public int PersonID { get; set; } [Display(Name = "姓名")] //添加Remote特性[Remote("CheckUserName", "ControllerName",ErrorMessage="用戶(hù)名已存在")] [Required(ErrorMessage = "不能為空")] public string Name { get; set; } [Display(Name = "手機號")] [Required(ErrorMessage = "不能為空")] [DataType(DataType.PhoneNumber)] public string PhoneNum { get; set; } }我們只需添加一個(gè)Remote特性就可以實(shí)現用戶(hù)名的服務(wù)端驗證。節省了js的代碼。
修改Action
Asp.Net MVC默認是不允許Get請求Json(防止Json被劫持)。所以如果你需要Get請求Json。必須添加JsonRequestBehavior.AllowGet。且該數據不那么重要。
//Actionpublic JsonResult CheckUserName(string Name){ //參數一定要和屬性名稱(chēng)一致bool result = true; if (Name == "admin") { result = false; } //添加JsonRequestBehavior.AllowGetreturn Json(result, JsonRequestBehavior.AllowGet);}Asp.Net MVC Ajax輔助方法可以讓我們更簡(jiǎn)便的使用Ajax。但是也要理解本身Ajajx的請求。
轉自:www.cnblogs.com/JoeSnail/p/7824930.html
聯(lián)系客服