Ajax(form表單檔案上傳、請求頭之contentType、Ajax傳遞json資料)
form表單檔案上傳
上菜
file_put.html
<form action="" method="post" enctype="multipart/form-data"> {# 這裡必須要請求頭格式才能把上傳檔案的物件傳過去 enctype="multipart/form-data"#} 姓名 <input type="text" name="user"> 頭像 <input type="file" name="head"> <input type="submit" > </form>
views.py
def file_put(request): if request.method == 'POST': print('post',request.POST) #只有 contenType== urlencoded request 才能拿到這個值 print(request.FILES) file_obj = request.FILES.get('head') with open(file_obj.name,'wb') as f: for line infile_obj: f.write(line) return HttpResponse('ok')
上面這個基於form 到表單上傳,在傳遞物件到時候必須要定義請求頭格式 nctype="multipart/form-data" 否則傳遞過來只是一個檔名稱,在服務端接收模版提交的內容必須使用 request.FILES 否則拿不到資料,通過建立檔案控制代碼,將傳遞資料迴圈讀取並寫入檔案,檔名稱就是接收檔案的name值。
請求頭之 contentType
$.ajax contentType 和 dataType , contentType 主要設定你傳送給伺服器的格式,dataType設定你收到伺服器資料的格式。
在http 請求中,get 和 post 是最常用的。在 jquery 的 ajax 中, contentType都是預設的值:application/x-www-form-urlencoded,這種格式的特點就是,name/value 成為一組,每組之間用 & 聯接,而 name與value 則是使用 = 連線。如: wwwh.baidu.com/q?key=fdsa&lang=zh 這是get , 而 post 請求則是使用請求體,引數不在 url 中,在請求體中的引數表現形式也是: key=fdsa&lang=zh的形式。
鍵值對這樣組織在一般的情況下是沒有什麼問題的,這裡說的一般是,不帶巢狀型別JSON,也就是 簡單的JSON,形如這樣:
{ a: 1, b: 2, c: 3 }
但是在一些複雜的情況下就有問題了。 例如在 ajax 中你要傳一個複雜的 json 對像,也就說是物件嵌陣列,陣列中包括物件,兄果你這樣傳:
{ data: { a: [{ x: 2 }] } }
這個複雜物件, application/x-www-form-urlencoded 這種形式是沒有辦法將複雜的 JSON 組織成鍵值對形式,你傳進去可以傳送請求,但是服務端收到資料為空, 因為 ajax 沒有辦法知道怎樣處理這個資料。
這怎麼可以呢?
聰明的程式設計師發現 http 還可以自定義資料型別,於是就定義一種叫 application/json 的型別。這種型別是 text , 我們 ajax 的複雜JSON資料,用 JSON.stringify序列化後,然後傳送,在伺服器端接到然後用 JSON.parse 進行還原就行了,這樣就能處理複雜的物件了。
$.ajax({ dataType: 'json', contentType: 'application/json', data: JSON.stringify({a: [{b:1, a:1}]}) })
這樣你就可以傳送複雜JSON的物件了。像現在的 restclient 都是這樣處理的。
Ajax傳遞json資料
file_put.html
<h1>ajax傳遞json資料</h1> <form action="" method="post"> 姓名<input type="text" name="user"> ajax<input type="submit" class="btn"> </form> <script> $('.btn').click(function () { $.ajax({ url:'', type:'post', contentType:'application/json', #這裡指定了傳輸編碼,用json進行傳輸 data:JSON.stringify({ #指定資料型別為json字串 a:1, b:2 }), success:function (data) { console.log(data) } }) })
views.py
def file_put(request): if request.method == 'POST': print('post------',request.POST) #只有 contenType== urlencoded request 才能拿到這個值 print('body------',request.body) #請求報文中的請求體 return render(request,'file_put.html')
#輸出
post------ <QueryDict: {}> body------ b'{"a":1,"b":2}' [06/Dec/2018 14:53:09] "POST /file_put/ HTTP/1.1" 200 963 post------ <QueryDict: {'user': ['']}> body------ b'user=' [06/Dec/2018 14:53:09] "POST /file_put/ HTTP/1.1" 200 963
可以看出這裡接收到的資料為json型別,如果本地想使用該資料,需要將json反序列化,也就是json.loads
下面看一下看預設情況下ajax 傳輸是按哪種編碼進行傳輸的
<script> $('.btn').click(function () { $.ajax({ url:'', type:'post', #contentType:'application/json', #data:JSON.stringify({ data:({ a:1, b:2 }), success:function (data) { console.log(data) } }) }) </script>
#輸出
post------ <QueryDict: {'a': ['1'], 'b': ['2']}> body------ b'a=1&b=2' [06/Dec/2018 14:56:08] "POST /file_put/ HTTP/1.1" 200 918 post------ <QueryDict: {'user': ['']}> body------ b'user=' [06/Dec/2018 14:56:08] "POST /file_put/ HTTP/1.1" 200 918
這裡看一看出body 裡是按照 預設的傳輸編碼 x-www-form-urlencoded 進行傳輸的
顯示的為 a=1&b=2 的格式,上面說過了這種格式對比較複雜對資料無法進行表示,所以只能使用json字串進行傳輸。