Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537 Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537
jax在前端開(kāi)發(fā)中有著舉足輕重的地位,關(guān)于Ajax的使用和注意事項(xiàng)一直是一個(gè)重要的話題,借此機(jī)會(huì),本文希望對(duì)Ajax做一個(gè)全面的總結(jié),徹底揭開(kāi)Ajax的神秘面紗。
Ajax(Asynchronous JavaScript and XML),可以理解為JavaScript執(zhí)行異步網(wǎng)絡(luò)請(qǐng)求。通俗的理解的話就是,如果沒(méi)有Ajax技術(shù),改變網(wǎng)頁(yè)的一小部分(哪怕是一行文字、一張圖片)都需要重新加載一次整個(gè)頁(yè)面,而有了Ajax之后,就可以實(shí)現(xiàn)在網(wǎng)頁(yè)不跳轉(zhuǎn)不刷新的情況下,在網(wǎng)頁(yè)后臺(tái)提交數(shù)據(jù),部分更新頁(yè)面內(nèi)容。
XMLHttpRequest 對(duì)象用于在后臺(tái)與服務(wù)器交換數(shù)據(jù),能夠在不重新加載頁(yè)面的情況下更新網(wǎng)頁(yè),在頁(yè)面已加載后從服務(wù)器請(qǐng)求數(shù)據(jù),在頁(yè)面已加載后從服務(wù)器接收數(shù)據(jù),在后臺(tái)向服務(wù)器發(fā)送數(shù)據(jù)。所以XMLHttpRequest對(duì)象是Ajax技術(shù)的核心所在。
創(chuàng)建 XMLHttpRequest對(duì)象——>打開(kāi)請(qǐng)求地址,初始化數(shù)據(jù)——>發(fā)送請(qǐng)求數(shù)據(jù)——>監(jiān)聽(tīng)回調(diào)函數(shù)狀態(tài)——>收到服務(wù)器返回的應(yīng)答結(jié)果。
下面用具體的代碼進(jìn)行解釋:
var xmlhttp; function loadXMLDoc(url) { xmlhttp=null; if (window.XMLHttpRequest) {// code for all new browsers xmlhttp=new XMLHttpRequest();//在這里創(chuàng)建 XMLHttpRequest對(duì)象 } else if (window.ActiveXObject) {// code for IE5 and IE6 xmlhttp=new ActiveXObject("Microsoft.XMLHTTP"); } if (xmlhttp!=null) { xmlhttp.open("GET",url,true); //請(qǐng)求的方式和請(qǐng)求地址 xmlhttp.send(null);//發(fā)送請(qǐng)求 xmlhttp.onreadystatechange=state_Change;//監(jiān)聽(tīng)回調(diào)函數(shù) } else { alert("Your browser does not support XMLHTTP."); } } function state_Change() //這里是回調(diào)函數(shù) { if (xmlhttp.readyState==4&&xmlhttp.status==200) //當(dāng)滿足這兩個(gè)條件時(shí)表示請(qǐng)求成功,完成響應(yīng) 4="loaded", 200=OK { var data=xmlhttp.responseText; //拿到服務(wù)器返回的數(shù)據(jù) // ...our code here...在這里進(jìn)行數(shù)據(jù)返回后的操作 }else { alert("Problem retrieving XML data"); } }
(1).open() 的第三個(gè)參數(shù)中使用了 "true",該參數(shù)規(guī)定請(qǐng)求是否異步處理,默認(rèn)是異步。True 表示腳本會(huì)在 send() 方法之后繼續(xù)執(zhí)行,而不等待來(lái)自服務(wù)器的響應(yīng)。
(2).關(guān)于readyState
(3).關(guān)于status 由服務(wù)器返回的 HTTP 狀態(tài)代碼,200 表示成功,而 404 表示 "Not Found" 錯(cuò)誤。當(dāng) readyState 小于 3 的時(shí)候讀取這一屬性會(huì)導(dǎo)致一個(gè)異常。(后面會(huì)有http狀態(tài)碼的詳細(xì)解讀)
JQuery對(duì)原生Ajax做了很好的封裝,使用起來(lái)非常簡(jiǎn)單方便,具體的很多方法如 $.ajax,$.post, $.get, $.getJSON等能根據(jù)不同需要進(jìn)行調(diào)用,寫(xiě)法更加簡(jiǎn)潔,但是為了兼顧各個(gè)方法在這里我以一個(gè)通用的方法 $.ajax為例做一個(gè)簡(jiǎn)單的解析,按照下面的模式寫(xiě)好各個(gè)參數(shù),就能成功進(jìn)行Ajax的請(qǐng)求了,可能在實(shí)際中使用 $.post, $.get 這兩個(gè)方法使用比較多,但是理解$.ajax 這個(gè)通用的方法能對(duì)封裝原理有很好的認(rèn)識(shí)。
$.ajax({ type: //數(shù)據(jù)的提交方式:get和post url: //請(qǐng)求地址 async: //是否支持異步刷新,默認(rèn)是true data: //需要提交的數(shù)據(jù) dataType: //服務(wù)器返回?cái)?shù)據(jù)的類(lèi)型,例如xml,String,Json等 success:function(data){ } //請(qǐng)求成功后的回調(diào)函數(shù),參數(shù)data就是服務(wù)器返回的數(shù)據(jù) error:function(data){ } //請(qǐng)求失敗后的回調(diào)函數(shù),根據(jù)需要可以不寫(xiě),一般只寫(xiě)上面的success回調(diào)函數(shù) })
作為Ajax最常用的兩種數(shù)據(jù)提交方式,GET和POST有著自己的特點(diǎn)和適用場(chǎng)景,正確區(qū)分GET和POST的不同并根據(jù)實(shí)際需要進(jìn)行選用在開(kāi)發(fā)中十分重要,簡(jiǎn)單但是關(guān)鍵!
先上一張GET 和 POST的比較圖,從這張圖中可以看出兩者之間的差別:
從表格中拎出關(guān)鍵點(diǎn): 1.傳遞數(shù)據(jù)的方式不同:get是直接把請(qǐng)求數(shù)據(jù)放在url的后面,是可見(jiàn)的,post的請(qǐng)求數(shù)據(jù)不會(huì)顯示在url中,是不可見(jiàn)的。 2.數(shù)據(jù)長(zhǎng)度和數(shù)據(jù)類(lèi)型的差異:get有數(shù)據(jù)長(zhǎng)度的的限制,且數(shù)據(jù)類(lèi)型只允許ASCII字符,post在這兩方面都沒(méi)有限制。 3.安全性的差異:get不安全,post更安全。
由此得出的兩者的使用場(chǎng)景:get使用較方便,適用于頁(yè)面之間非敏感數(shù)據(jù)的簡(jiǎn)單傳值,post使用較為安全,適用于向服務(wù)器發(fā)送密碼、token等敏感數(shù)據(jù)。
JQuery封裝的Ajax回調(diào)函數(shù)中,success、error、complete是最常用的三個(gè),其中,success和error很好區(qū)別,一個(gè)是請(qǐng)求成功調(diào)用的,另一個(gè)是請(qǐng)求失敗調(diào)用的,從字面上就可以理解。但是success和complete容易混淆,在這里特別做一個(gè)說(shuō)明:
success:請(qǐng)求成功后回調(diào)函數(shù)。
complete:請(qǐng)求完成后回調(diào)函數(shù) (請(qǐng)求成功或失敗時(shí)均調(diào)用)。
注意到括號(hào)里面了嗎,沒(méi)錯(cuò),區(qū)別就在于complete只要請(qǐng)求完成,不論是成功還是失敗均會(huì)調(diào)用。也就是說(shuō)如果調(diào)用了success,一定會(huì)調(diào)用complete;反過(guò)來(lái)調(diào)用了complete,不一定會(huì)調(diào)用success。(狀態(tài)碼404、403、301、302...都會(huì)進(jìn)入complete,只要不出錯(cuò)就會(huì)調(diào)用)
Ajax中的是 "x" 指的就是XML。
xml:可擴(kuò)展標(biāo)記語(yǔ)言,標(biāo)準(zhǔn)通用標(biāo)記語(yǔ)言的子集,是一種用于標(biāo)記電子文件使其具有結(jié)構(gòu)性的標(biāo)記語(yǔ)言。
xml作為一種數(shù)據(jù)交互格式,廣泛用在計(jì)算機(jī)領(lǐng)域,然而,隨著json的發(fā)展,json以其明顯的優(yōu)勢(shì)已經(jīng)漸漸取代了xml成為現(xiàn)在數(shù)據(jù)交互格式的標(biāo)準(zhǔn),所以在這里,想強(qiáng)調(diào)的是,json現(xiàn)在是主流的數(shù)據(jù)交互格式,前后端的交互標(biāo)準(zhǔn),無(wú)論是前端提交給后臺(tái)的數(shù)據(jù),還是后臺(tái)返回給前端的數(shù)據(jù),都最好統(tǒng)一為json格式,各自接收到數(shù)據(jù)后再解析數(shù)據(jù)即可供后續(xù)使用。所以 "Ajax" 實(shí)際上已經(jīng)發(fā)展為 "Ajaj"
json 和 jsonp 看起來(lái)只相差了一個(gè) “p” ,然而實(shí)際上根本不是一個(gè)東西,千萬(wàn)別以為是差不多的兩個(gè)概念。
json:(JavaScript Object Notation, JS 對(duì)象標(biāo)記) 是一種輕量級(jí)的數(shù)據(jù)交換格式。
jsonp:一種借助 <script> 元素解決主流瀏覽器的跨域數(shù)據(jù)訪問(wèn)問(wèn)題的方式。
ajax很好,但不是萬(wàn)能的,ajax的請(qǐng)求與訪問(wèn)同樣會(huì)受到瀏覽器同源策略的限制,不能訪問(wèn)不同主域中的地址。所以,為了解決這一問(wèn)題,實(shí)現(xiàn)跨域訪問(wèn),有很多種方式,上述提到的jsonp就是一種流行的方式,還有其他一些方式,我在這里就不展開(kāi)說(shuō)了,只是想說(shuō)明ajax的使用也是有條件的,任何技術(shù)的實(shí)現(xiàn)都不會(huì)是沒(méi)有限制的。跨域訪問(wèn)時(shí)一個(gè)很重要的知識(shí)點(diǎn),之前專門(mén)寫(xiě)過(guò)一篇關(guān)于跨域訪問(wèn)的總結(jié),還挺詳細(xì)的,可以移步查看: javascript中實(shí)現(xiàn)跨域的方式總結(jié)
前面提到的"200"、"404"只是http狀態(tài)碼中常見(jiàn)的兩個(gè),當(dāng)瀏覽者訪問(wèn)一個(gè)網(wǎng)頁(yè)時(shí),瀏覽者的瀏覽器會(huì)向網(wǎng)頁(yè)所在服務(wù)器發(fā)出請(qǐng)求。當(dāng)瀏覽器接收并顯示網(wǎng)頁(yè)前,此網(wǎng)頁(yè)所在的服務(wù)器會(huì)返回一個(gè)包含HTTP狀態(tài)碼的信息頭(server header)用以響應(yīng)瀏覽器的請(qǐng)求。
需要掌握的常見(jiàn)http狀態(tài)碼大致有以下一些:
101:切換協(xié)議,服務(wù)器根據(jù)客戶端的請(qǐng)求切換協(xié)議 **200:請(qǐng)求成功。一般用于GET與POST請(qǐng)求** **301:永久重定向** **302:臨時(shí)重定向** 303:與301類(lèi)似。使用GET和POST請(qǐng)求查看 **304:請(qǐng)求資源未修改,使用緩存** 307:與302類(lèi)似。使用GET請(qǐng)求重定向 **404:客戶端請(qǐng)求失敗** 408:請(qǐng)求超時(shí) **500:內(nèi)部服務(wù)器錯(cuò)誤,無(wú)法完成請(qǐng)求** 505:服務(wù)器不支持請(qǐng)求的HTTP協(xié)議的版本,無(wú)法完成處理
http請(qǐng)求中的一個(gè)重要關(guān)注點(diǎn)就是請(qǐng)求頭和響應(yīng)頭的內(nèi)容,從這兩個(gè)頭文件中可以看出很多東西,當(dāng)我們用發(fā)送一個(gè)ajax請(qǐng)求的時(shí)候,如果沒(méi)有達(dá)到預(yù)期的效果,那么就需要打開(kāi)瀏覽器的調(diào)試工具,從NetWork中找到相應(yīng)的ajax請(qǐng)求,再通過(guò)查看請(qǐng)求頭和響應(yīng)頭的信息,大體會(huì)知道這次請(qǐng)求的結(jié)果是怎么樣的,結(jié)合響應(yīng)的主體內(nèi)容,可以很快找到問(wèn)題。所以學(xué)會(huì)看http的頭文件信息是前端開(kāi)發(fā)中必須掌握的一個(gè)技能,下面就來(lái)看看具體的頭文件信息。
首先隨便上一張sf中的完成一個(gè)搜索結(jié)果的http請(qǐng)求,可以從圖中的右側(cè)清楚看到請(qǐng)求頭和響應(yīng)頭的內(nèi)容,包括了很多個(gè)字段信息,這些字段信息就是我們需要掌握的知識(shí)點(diǎn),下面挑出其中的重點(diǎn)字段進(jìn)行分析。
Accept:客戶端支持的數(shù)據(jù)類(lèi)型 Accept-Charset:客戶端采用的編碼 Accept-Encoding:客戶端支持的數(shù)據(jù)壓縮格式 Accept-Language:客戶端的語(yǔ)言環(huán)境 Cookie:客服端的cookie Host:請(qǐng)求的服務(wù)器地址 Connection:客戶端與服務(wù)連接類(lèi)型 If-Modified-Since:上一次請(qǐng)求資源的緩存時(shí)間,與Last-Modified對(duì)應(yīng) If-None-Match:客戶段緩存數(shù)據(jù)的唯一標(biāo)識(shí),與Etag對(duì)應(yīng) Referer:發(fā)起請(qǐng)求的源地址。
content-encoding:響應(yīng)數(shù)據(jù)的壓縮格式。 content-length:響應(yīng)數(shù)據(jù)的長(zhǎng)度。 content-language:語(yǔ)言環(huán)境。 content-type:響應(yīng)數(shù)據(jù)的類(lèi)型。 Date:消息發(fā)送的時(shí)間 Age:經(jīng)過(guò)的時(shí)間 Etag:被請(qǐng)求變量的實(shí)體值,用于判斷請(qǐng)求的資源是否發(fā)生變化 Expires:緩存的過(guò)期時(shí)間 Last-Modified:在服務(wù)器端最后被修改的時(shí)間 server:服務(wù)器的型號(hào)
Pragma:是否緩存(http1.0提出) Cache-Control:是否緩存(http1.1提出)
(1) 強(qiáng)制緩存 expire 和 cache-control
(2) 對(duì)比緩存 Last-Modified 和 If-Modified-Since Etag 和 If-None-Match
安全問(wèn)題,對(duì)一些網(wǎng)站攻擊,如csrf、xxs、sql注入等不能很好地防御。
* JSON 使用 JavaScript 語(yǔ)法來(lái)描述數(shù)據(jù)對(duì)象,但是 JSON 仍然獨(dú)立于語(yǔ)言和平臺(tái)。JSON 解析器和 JSON 庫(kù)支持許多不同的編程語(yǔ)言。
合格的json對(duì)象:
["one", "two", "three"]
{ "one": 1, "two": 2, "three": 3 }
{"names": ["張三", "李四"] }
[ { "name": "張三"}, {"name": "李四"} ]
不合格的json對(duì)象:
{ name: "張三", 'age': 32 } // 屬性名必須使用雙引號(hào)
[32, 64, 128, 0xFFF] // 不能使用十六進(jìn)制值
{ "name": "張三", "age": undefined } // 不能使用undefined
{ "name": "張三",
"birthday": new Date('Fri, 26 Aug 2011 07:13:10 GMT'),
"getName": function() {return this.name;} // 不能使用函數(shù)和日期對(duì)象
}
JavaScript中關(guān)于JSON對(duì)象和字符串轉(zhuǎn)換的兩個(gè)方法:
JSON.parse(): 用于將一個(gè) JSON 字符串轉(zhuǎn)換為 JavaScript 對(duì)象
JSON.parse('{"name":"run1"}');
JSON.parse('{name:"run1"}') ; // 錯(cuò)誤
JSON.parse('[18,undefined]') ; // 錯(cuò)誤
JSON.stringify(): 用于將 JavaScript 值轉(zhuǎn)換為 JSON 字符串。
JSON.stringify({"name":"run1"})
JSON 格式于2001年由 Douglas Crockford 提出,目的就是取代繁瑣笨重的 XML 格式。
JSON 格式有兩個(gè)顯著的優(yōu)點(diǎn):書(shū)寫(xiě)簡(jiǎn)單,一目了然;符合 JavaScript 原生語(yǔ)法,可以由解釋引擎直接處理,不用另外添加解析代碼。所以,JSON迅速被接受,已經(jīng)成為各大網(wǎng)站交換數(shù)據(jù)的標(biāo)準(zhǔn)格式,并被寫(xiě)入ECMAScript 5,成為標(biāo)準(zhǔn)的一部分。
XML和JSON都使用結(jié)構(gòu)化方法來(lái)標(biāo)記數(shù)據(jù),下面來(lái)做一個(gè)簡(jiǎn)單的比較。
用XML表示中國(guó)部分省市數(shù)據(jù)如下:
<?xml version="1.0" encoding="utf-8"?>
<country>
<name>中國(guó)</name>
<province>
<name>黑龍江</name>
<cities>
<city>哈爾濱</city>
<city>大慶</city>
</cities>
</province>
<province>
<name>廣東</name>
<cities>
<city>廣州</city>
<city>深圳</city>
<city>珠海</city>
</cities>
</province>
<province>
<name>臺(tái)灣</name>
<cities>
<city>臺(tái)北</city>
<city>高雄</city>
</cities>
</province>
<province>
<name>新疆</name>
<cities>
<city>烏魯木齊</city>
</cities>
</province>
</country>
用JSON表示如下
{
"name": "中國(guó)",
"province": [{
"name": "黑龍江",
"cities": {
"city": ["哈爾濱", "大慶"]
}
}, {
"name": "廣東",
"cities": {
"city": ["廣州", "深圳", "珠海"]
}
}, {
"name": "臺(tái)灣",
"cities": {
"city": ["臺(tái)北", "高雄"]
}
}, {
"name": "新疆",
"cities": {
"city": ["烏魯木齊"]
}
}]
}
由上面的兩段代碼可以看出,JSON 簡(jiǎn)單的語(yǔ)法格式和清晰的層次結(jié)構(gòu)明顯要比 XML 容易閱讀,并且在數(shù)據(jù)交換方面,由于 JSON 所使用的字符要比 XML 少得多,可以大大得節(jié)約傳輸數(shù)據(jù)所占用的帶寬。
AJAX(Asynchronous Javascript And XML)翻譯成中文就是“異步Javascript和XML”。即使用Javascript語(yǔ)言與服務(wù)器進(jìn)行異步交互,傳輸?shù)臄?shù)據(jù)為XML(當(dāng)然,傳輸?shù)臄?shù)據(jù)不只是XML)。
AJAX除了異步的特點(diǎn)外,還有一個(gè)就是:瀏覽器頁(yè)面局部刷新;(這一特點(diǎn)給用戶的感受是在不知不覺(jué)中完成請(qǐng)求和響應(yīng)過(guò)程)
示例:
頁(yè)面輸入兩個(gè)整數(shù),通過(guò)AJAX傳輸?shù)胶蠖擞?jì)算出結(jié)果并返回。
HTML部分代碼
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="x-ua-compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>AJAX局部刷新實(shí)例</title>
</head>
<body>
<input type="text" id="i1">+
<input type="text" id="i2">=<input type="text" id="i3">
<input type="button" value="AJAX提交" id="b1">
<script src="/static/jquery-3.2.1.min.js"></script>
<script>
$("#b1").on("click", function () {
$.ajax({
url:"/ajax_add/",
type:"GET",
data:{"i1":$("#i1").val(),"i2":$("#i2").val()},
success:function (data) {
$("#i3").val(data);
}
})
})
</script>
</body>
</html>
views.py
def ajax_demo1(request):
return render(request, "ajax_demo1.html")
def ajax_add(request):
i1=int(request.GET.get("i1"))
i2=int(request.GET.get("i2"))
ret=i1 + i2
return JsonResponse(ret, safe=False)
urls.py
urlpatterns=[
...
url(r'^ajax_add/', views.ajax_add),
url(r'^ajax_demo1/', views.ajax_demo1),
...
]
$.ajax({
url:"", // 控制往哪里提交
type:"POST", // 請(qǐng)求的方法
data:{}, // 請(qǐng)求的參數(shù)
success:function(arg){
// 收到響應(yīng)之后要做的事
}
})
搜索引擎根據(jù)用戶輸入的關(guān)鍵字,自動(dòng)提示檢索關(guān)鍵字。
還有一個(gè)很重要的應(yīng)用場(chǎng)景就是注冊(cè)時(shí)候的用戶名的查重。
其實(shí)這里就使用了AJAX技術(shù)!當(dāng)文件框發(fā)生了輸入變化時(shí),使用AJAX技術(shù)向服務(wù)器發(fā)送一個(gè)請(qǐng)求,然后服務(wù)器會(huì)把查詢到的結(jié)果響應(yīng)給瀏覽器,最后再把后端返回的結(jié)果展示出來(lái)。
當(dāng)輸入用戶名后,把光標(biāo)移動(dòng)到其他表單項(xiàng)上時(shí),瀏覽器會(huì)使用AJAX技術(shù)向服務(wù)器發(fā)出請(qǐng)求,服務(wù)器會(huì)查詢名為lemontree7777777的用戶是否存在,最終服務(wù)器返回true表示名為lemontree7777777的用戶已經(jīng)存在了,瀏覽器在得到結(jié)果后顯示“用戶名已被注冊(cè)!”。
優(yōu)點(diǎn)
最基本的jQuery發(fā)送AJAX請(qǐng)求示例
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta http-equiv="x-ua-compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>ajax test</title>
<script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.min.js"></script>
</head>
<body>
<button id="ajaxTest">AJAX 測(cè)試</button>
<script>
$("#ajaxTest").click(function () {
$.ajax({
url: "/ajax_test/",
type: "POST",
data: {username: "Q1mi", password: 123456},
success: function (data) {
alert(data)
}
})
})
</script>
</body>
</html>
views.py
def ajax_test(request):
user_name=request.POST.get("username")
password=request.POST.get("password")
print(user_name, password)
return HttpResponse("OK")
$.ajax參數(shù)
data參數(shù)中的鍵值對(duì),如果值值不為字符串,需要將其轉(zhuǎn)換成字符串類(lèi)型。
$("#b1").on("click", function () {
$.ajax({
url:"/ajax_add/",
type:"GET",
data:{"i1":$("#i1").val(),"i2":$("#i2").val(),"hehe": JSON.stringify([1, 2, 3])},
success:function (data) {
$("#i3").val(data);
}
})
})
方式1
通過(guò)獲取隱藏的input標(biāo)簽中的csrfmiddlewaretoken值,放置在data中發(fā)送。
$.ajax({
url: "/cookie_ajax/",
type: "POST",
data: {
"username": "rum2",
"password": 123456,
"csrfmiddlewaretoken": $("[name='csrfmiddlewaretoken']").val() // 使用JQuery取出csrfmiddlewaretoken的值,拼接到data中
},
success: function (data) {
console.log(data);
}
})
通過(guò)獲取返回的cookie中的字符串 放置在請(qǐng)求頭中發(fā)送。
注意:需要引入一個(gè)jquery.cookie.js插件。
$.ajax({
url: "/cookie_ajax/",
type: "POST",
headers: {"X-CSRFToken": $.cookie('csrftoken')}, // 從Cookie取csrf_token,并設(shè)置ajax請(qǐng)求頭
data: {"username": "rum", "password": 123456},
success: function (data) {
console.log(data);
}
})
或者用自己寫(xiě)一個(gè)getCookie方法:
function getCookie(name) {
var cookieValue=null;
if (document.cookie && document.cookie !=='') {
var cookies=document.cookie.split(';');
for (var i=0; i < cookies.length; i++) {
var cookie=jQuery.trim(cookies[i]);
// Does this cookie string begin with the name we want?
if (cookie.substring(0, name.length + 1)===(name + '=')) {
cookieValue=decodeURIComponent(cookie.substring(name.length + 1));
break;
}
}
}
return cookieValue;
}
var csrftoken=getCookie('csrftoken');
每一次都這么寫(xiě)太麻煩了,可以使用$.ajaxSetup()方法為ajax請(qǐng)求統(tǒng)一設(shè)置。
function csrfSafeMethod(method) {
// these HTTP methods do not require CSRF protection
return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
}
$.ajaxSetup({
beforeSend: function (xhr, settings) {
if (!csrfSafeMethod(settings.type) && !this.crossDomain) {
xhr.setRequestHeader("X-CSRFToken", csrftoken);
}
}
});
Django內(nèi)置的serializers
def books_json(request):
book_list=models.Book.objects.all()[0:10]
from django.core import serializers
ret=serializers.serialize("json", book_list)
return HttpResponse(ret)
我們的數(shù)據(jù)中經(jīng)常有日期時(shí)間,也就是datetime對(duì)象,而json.dumps是無(wú)法處理這樣在類(lèi)型的,那就需要通過(guò)自定義處理器來(lái)做擴(kuò)展,如下:
class JsonCustomEncoder(json.JSONEncoder):
"""
自定義一個(gè)支持序列化時(shí)間格式的類(lèi)
"""
def default(self, o):
if isinstance(o, datetime):
return o.strftime("%Y-%m-%d %H:%M:%S")
elif isinstance(o, date):
return o.strftime("%Y-%m-%d")
else:
return json.JSONEncoder.default(self, o)
def books_json(request):
book_list=models.Book.objects.all().values_list("title", "publish_date")
ret=json.dumps(list(book_list), cls=JsonCustomEncoder)
return HttpResponse(ret)
Bootstrap-sweetalert
https://github.com/lipis/bootstrap-sweetalert
$(".btn-danger").on("click", function () {
swal({
title: "你確定要?jiǎng)h除嗎?",
text: "刪除可就找不回來(lái)了哦!",
type: "warning",
showCancelButton: true,
confirmButtonClass: "btn-danger",
confirmButtonText: "刪除",
cancelButtonText: "取消",
closeOnConfirm: false
},
function () {
var deleteId=$(this).parent().parent().attr("data_id");
$.ajax({
url: "/delete_book/",
type: "post",
data: {"id": deleteId},
success: function (data) {
if (data.status===1) {
swal("刪除成功!", "你可以準(zhǔn)備跑路了!", "success");
} else {
swal("刪除失敗", "你可以再嘗試一下!", "error")
}
}
})
});
})
#科技##軟件開(kāi)發(fā)##python#
AJAX 即“Asynchronous Javascript And XML”(異步 JavaScript 和 XML),是指一種創(chuàng)建交互式網(wǎng)頁(yè)應(yīng)用的網(wǎng)頁(yè)開(kāi)發(fā) 技術(shù)。
ajax 是一種瀏覽器通過(guò) js 異步發(fā)起請(qǐng)求,局部更新頁(yè)面的技術(shù)。
Ajax 請(qǐng)求的局部更新,瀏覽器地址欄不會(huì)發(fā)生變化
局部更新不會(huì)舍棄原來(lái)頁(yè)面的內(nèi)容
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="pragma" content="no-cache" />
<meta http-equiv="cache-control" content="no-cache" />
<meta http-equiv="Expires" content="0" />
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
<script type="text/javascript">
// 在這里使用 javaScript 語(yǔ)言發(fā)起 Ajax 請(qǐng)求,訪問(wèn)服務(wù)器 AjaxServlet 中 javaScriptAjax
function ajaxRequest() {
// 我們首先要?jiǎng)?chuàng)建 XMLHttpRequest
var xmlhttprequest=new XMLHttpRequest();
// 調(diào)用 open 方法設(shè)置請(qǐng)求參數(shù)
xmlhttprequest.open("GET","http://localhost:8080/Test/ajaxServlet?action=javaScriptAj
ax",true)
// 在 send 方法前綁定 onreadystatechange 事件,處理請(qǐng)求完成后的操作。
xmlhttprequest.onreadystatechange=function(){
if (xmlhttprequest.readyState==4 && xmlhttprequest.status==200) {
var jsonObj=JSON.parse(xmlhttprequest.responseText);
// 把響應(yīng)的數(shù)據(jù)顯示在頁(yè)面上
document.getElementById("div01").innerHTML=" 編號(hào):" + jsonObj.id + " , 姓名:" +
jsonObj.name;
}
}
// 調(diào)用 send 方法發(fā)送請(qǐng)求
xmlhttprequest.send();
}
</script>
</head>
<body>
<button onclick="ajaxRequest()">ajax request</button>
<div id="div01">
</div>
</body>
</html>
$.ajax 方法
url 表示請(qǐng)求的地址
type 表示請(qǐng)求的類(lèi)型 GET 或 POST 請(qǐng)求
data 表示發(fā)送給服務(wù)器的數(shù)據(jù)
格式有兩種:
一:name=value&name=value
二:{key:value}
success 請(qǐng)求成功,響應(yīng)的回調(diào)函數(shù)
dataType 響應(yīng)的數(shù)據(jù)類(lèi)型
常用的數(shù)據(jù)類(lèi)型有:
text 表示純文本
xml 表示 xml 數(shù)據(jù)
json 表示 json 對(duì)象
$("#ajaxBtn").click(function(){
$.ajax({
url:"http://localhost:8080/Test/ajaxServlet",
// data:"action=jQueryAjax",
data:{action:"jQueryAjax"},
type:"GET",
success:function (data) {
// alert(" 服務(wù)器返回的數(shù)據(jù)是: " + data);
// var jsonObj=JSON.parse(data);
$("#msg").html(" 編號(hào):" + data.id + " , 姓名:" + data.name);
},
dataType : "json"
});
});
方法和.post 方法
url 請(qǐng)求的 url 地址
data 發(fā)送的數(shù)據(jù)
callback 成功的回調(diào)函數(shù)
type 返回的數(shù)據(jù)類(lèi)型
// ajax--get 請(qǐng)求
$("#getBtn").click(function(){
$.get("http://localhost:8080/Test/ajaxServlet","action=jQueryGet",function (data) {
$("#msg").html(" get 編號(hào):" + data.id + " , 姓名:" + data.name);
},"json");
});
// ajax--post 請(qǐng)求
$("#postBtn").click(function(){
$.post("http://localhost:8080/Test/ajaxServlet","action=jQueryPost",function (data)
{
$("#msg").html(" post 編號(hào):" + data.id + " , 姓名:" + data.name);
},"json");
});
$.getJSON 方法
url 請(qǐng)求的 url 地址
data 發(fā)送給服務(wù)器的數(shù)據(jù)
callback 成功的回調(diào)函數(shù)
// ajax--getJson 請(qǐng)求
$("#getJSONBtn").click(function(){
$.getJSON("http://localhost:8080/Test/ajaxServlet","action=jQueryGetJSON",function
(data) {
$("#msg").html(" getJSON 編號(hào):" + data.id + " , 姓名:" + data.name);
});
});
表單序列化 serialize() serialize()可以把表單中所有表單項(xiàng)的內(nèi)容都獲取到,并以 name=value&name=value 的形式進(jìn)行拼接。
// ajax 請(qǐng)求
$("#submit").click(function(){
// 把參數(shù)序列化
$.getJSON("http://localhost:8080/Test/ajaxServlet","action=jQuerySerialize&" +
$("#form01").serialize(),function (data) {
$("#msg").html(" Serialize 編號(hào):" + data.id + " , 姓名:" + data.name);
});
});
歡迎關(guān)注公眾號(hào):愚生淺末。
*請(qǐng)認(rèn)真填寫(xiě)需求信息,我們會(huì)在24小時(shí)內(nèi)與您取得聯(lián)系。