前端往後端發送數據的幾種方法
先來談談XmlHttpRequest對象
XmlHttpRequest對象的主要方法:
a. void open(String method,String url,Boolen async) 用於創建請求 參數: method: 請求方式(字符串類型),如:POST、GET、DELETE... url: 要請求的地址(字符串類型) async: 是否異步(布爾類型) b. void send(String body) 用於發送請求 參數: body: 要發送的數據(字符串類型) c. void setRequestHeader(String header,String value) 用於設置請求頭 參數: header: 請求頭的key(字符串類型) vlaue: 請求頭的value(字符串類型) d. String getAllResponseHeaders() 獲取所有響應頭 返回值: 響應頭數據(字符串類型) e. String getResponseHeader(String header) 獲取響應頭中指定header的值 參數: header: 響應頭的key(字符串類型) 返回值: 響應頭中指定的header對應的值 f. void abort() 終止請求
XmlHttpRequest對象的主要屬性:
a. Number readyState 狀態值(整數) 詳細: 0-未初始化,尚未調用open()方法; 1-啟動,調用了open()方法,未調用send()方法; 2-發送,已經調用了send()方法,未接收到響應; 3-接收,已經接收到部分響應數據; 4-完成,已經接收到全部響應數據; b. Function onreadystatechange 當readyState的值改變時自動觸發執行其對應的函數(回調函數) c. String responseText 服務器返回的數據(字符串類型) d. XmlDocument responseXML 服務器返回的數據(Xml對象) e. Number states 狀態碼(整數),如:200、404... f. String statesText 狀態文本(字符串),如:OK、NotFound...
**原生jquery XMLHttpRequest 生成對象;
什麽情況需要寫原生jquery 例如:手機 手機流量缺失就不會先加載jquery
‘GET‘請求 function AjaxSubmit2() { var xhr = new XMLHttpRequest(); //設置回調函數 xhr.onreadystatechange = function (ev) { if (xhr.readyState == 4){ //接收完畢服務器返回的數據 console.log(xhr.responseText); } }; xhr.open(‘GET‘,‘/ajax1?p=123‘); xhr.send(null) }‘POST‘請求 帶上請求頭 setRequestHeader function AjaxSubmit2() { var xhr = new XMLHttpRequest(); //設置回調函數 xhr.onreadystatechange = function (ev) { if (xhr.readyState == 4){ //接收完畢服務器返回的數據 console.log(xhr.responseText); } }; xhr.open(‘POST‘,‘/ajax1?p=123‘); xhr.setRequestHeader(‘Content-Type‘, ‘application/x-www-form-urlencoded; charset-UTF-8‘); xhr.send(‘P=234‘) }
下面介紹一下 偽Ajax
Iframe+form 實現
其利用 iframe 【不刷新的特性】 和 form 【提交數據的特性】
<iframe id="iframe" name="ifra"></iframe> <form id="fm" action="/ajax1.html" method="POST" target="ifra"> <input name="root" value="111111" /> <input type=‘submit‘ value=‘提交‘> </form>實現
什麽時候iframe才開始取數據呢?引出第二種方法
當點擊提交的時候才綁定事件
<iframe id="iframe" name="ifra"></iframe> <form id="fm" action="/ajax1.html" method="POST" target="ifra"> <input name="root" value="111111" /> <a onclick="AjaxSubmit5()">提交</a> </form> function AjaxSubmit5() { document.getElementById(‘iframe‘).onload = reloadIframe; //在數據提交之間綁定事件 document.getElementById(‘fm‘).submit(); } function reloadIframe() { // this=當前標簽 //console.log(ths); //console.log(ths.contentWindow); //console.log(ths.contentWindow.document.body.innerHTML); //console.log($(ths).contents().find(‘body‘).html()); var content = this.contentWindow.document.body.innerHTML; var obj = JSON.parse(content); //轉換成對象 對象ret = {‘status‘:‘‘,‘message‘:‘‘} if(obj.status){ alert(obj.message); } }View Code
再來介紹一下ajxa
jQuery.get(...)
所有參數:
url: 待載入頁面的URL地址
data: 待發送 Key/value 參數。
success: 載入成功時回調函數。
dataType: 返回內容格式,xml, json, script, text, html
jQuery.post(...)
所有參數:
url: 待載入頁面的URL地址
data: 待發送 Key/value 參數
success: 載入成功時回調函數
dataType: 返回內容格式,xml, json, script, text, html
jQuery.getJSON(...)
所有參數:
url: 待載入頁面的URL地址
data: 待發送 Key/value 參數。
success: 載入成功時回調函數。
jQuery.getScript(...)
所有參數:
url: 待載入頁面的URL地址
data: 待發送 Key/value 參數。
success: 載入成功時回調函數。
jQuery.ajax(...)
部分參數:
url:請求地址
type:請求方式,GET、POST(1.9.0之後用method)
headers:請求頭
data:要發送的數據
contentType:即將發送信息至服務器的內容編碼類型(默認: "application/x-www-form-urlencoded; charset=UTF-8")
async:是否異步
timeout:設置請求超時時間(毫秒)
beforeSend:發送請求前執行的函數(全局)
complete:完成之後執行的回調函數(全局)
success:成功之後執行的回調函數(全局)
error:失敗之後執行的回調函數(全局)
accepts:通過請求頭發送給服務器,告訴服務器當前客戶端課接受的數據類型
dataType:將服務器端返回的數據轉換成指定類型
"xml": 將服務器端返回的內容轉換成xml格式
"text": 將服務器端返回的內容轉換成普通文本格式
"html": 將服務器端返回的內容轉換成普通文本格式,在插入DOM中時,如果包含JavaScript標簽,則會嘗試去執行。
"script": 嘗試將返回值當作JavaScript去執行,然後再將服務器端返回的內容轉換成普通文本格式
"json": 將服務器端返回的內容轉換成相應的JavaScript對象
"jsonp": JSONP 格式
使用 JSONP 形式調用函數時,如 "myurl?callback=?" jQuery 將自動替換 ? 為正確的函數名,以執行回調函數
如果不指定,jQuery 將自動根據HTTP包MIME信息返回相應類型(an XML MIME type will yield XML, in 1.4 JSON will yield a JavaScript object, in 1.4 script will execute the script, and anything else will be returned as a string
converters: 轉換器,將服務器端的內容根據指定的dataType轉換類型,並傳值給success回調函數
$.ajax({
accepts: {
mycustomtype: ‘application/x-some-custom-type‘
},
// Expect a `mycustomtype` back from server
dataType: ‘mycustomtype‘
// Instructions for how to deserialize a `mycustomtype`
converters: {
‘text mycustomtype‘: function(result) {
// Do Stuff
return newresult;
}
},
});
jQuery Ajax 方法列表
第二部分 通過ajax上傳文件
1.JQuery
2.原生 XMLHttpRequest(send)
以上兩種方式可利用formData對象,來封裝用戶提交的數據
3.Iframe+Form
<input type="file" id=‘img‘> 1.formdata function AjaxSubmit6() { //document.getElementById(‘img‘)[0] var data = new FormData(); data.append(‘k1‘,‘v1‘); data.append(‘k2‘,‘v2‘); data.append(‘k3‘,document.getElementById(‘img‘).files[0]); $.ajax({ url: ‘/ajax1.html‘, type: ‘POST‘, data:data, //本來這裏是寫字典的 ******現在用高級的方法**** success:function (arg) { console.log(arg) }, //需要加上這兩個參數 //這兩個參數告訴jquery不用幫我處理數據 直接上傳就行啦 processData: false, // tell jQuery not to process the data contentType: false // tell jQuery not to set contentType }) }View Code
2.formdata 可以幫忙封裝數據 包括文件對象
function AjaxSubmit7() {
var data = new FormData();
data.append(‘k1‘,‘v1‘);
data.append(‘k2‘,‘v2‘);
data.append(‘k3‘,document.getElementById(‘img‘).files[0]);
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function () {
if(xhr.readyState == 4){
// 接收完畢服務器返回的數據
console.log(xhr.responseText);
}
};
xhr.open(‘POST‘,‘/ajax1.html‘);
xhr.send(data);
}
3.Iframe+Form 的上傳文件 <iframe style="display: none" id="iframe1" name="ifra1"></iframe> <form id="fm1" action="/ajax1.html" method="POST" enctype="multipart/form-data" target="ifra1"> <input type="text" name="k1" /> <input type="text" name="k2" /> <input type="file" name="k3" /> <a onclick="AjaxSubmit8()">提交</a> </form> function AjaxSubmit8() { document.getElementById(‘iframe1‘).onload = reloadIframe1; document.getElementById(‘fm1‘).submit(); } function reloadIframe1() { var content = this.contentWindow.document.body.innerHTML; var obj = JSON.parse(content); console.log(obj); }
總結:用哪種方法? 目前都可以用formData 考慮低版本就是iframe+Form(兼容性強)
第三部分:跨域Ajax------------------>JSONP
什麽叫跨域:
由於瀏覽器存在同源策略機制,同源策略阻止從一個源加載的文檔或腳本獲取或設置另一個源加載的文檔的屬性。
特別的:由於同源策略是瀏覽器的限制,所以請求的發送和響應是可以進行,只不過瀏覽器不接受罷了。
瀏覽器同源策略並不是對所有的請求均制約:
- 制約: XmlHttpRequest
- 不制約: img、iframe、script等具有src屬性的標簽
跨域,跨域名訪問,如:http://www.c1.com 域名向 http://www.c2.com域名發送請求。
解決方法:
巧妙的機制:JSONP(是一種方式 script+後端返回方法名+不斷添加刪除子標簽
JSONP:
利用創建script塊,在期中執行src屬性為:遠程url
由網站後端 提供一個函數返回值
function 函數(arg){
}
第一種: 利用script的src特性 可以跨域訪問 後端返回函數 ----手動
view.py def jsonp(request): return HttpResponse("func(‘我要上鴨王‘)"); #返回一個函數 .html function submitJsonp3() { var tag = document.createElement(‘script‘); tag.src = ‘http://www.jxntv.cn/data/jmd-jxtv2.html?callback=list&tt=1454376870403‘; document.head.appendChild(tag); document.head.removeChild(tag); } # 寫一個後端返回同名的函數 function func(arg) { console.log(arg); }
第一種要自己寫 ---------->引出第二種
第二種 JQuery 自動 生成script標簽 但是拿到返回值就刪除這個標簽
view.py
def jsonp(request):
return HttpResponse("func(‘我要上鴨王‘)"); #返回一個函數
test.html
function submitJsonp4() {
$.ajax({
url: ‘http://127.0.0.1:9000/xiaokai.html‘,
type: ‘POST‘,
dataType: ‘jsonp‘,
})
}
# 寫一個後端返回同名的函數
function func(arg) {
console.log(arg);
}
第二種還有缺陷?我怎麽知道後端返回的函數名
引出第三種 把函數放在訪問url中
function submitJsonp4() {
$.ajax({
url: ‘http://127.0.0.1:9000/xiaokai.html?callback=func‘,
type: ‘GET‘,
dataType: ‘jsonp‘,
})
}
# 寫一個後端返回同名的函數
function func(arg) {
console.log(arg);
}
但是這個還不夠好 這裏有個別人寫好的
*******************引出別人寫好的*****************************
def view(request):
callback = request.GET.get(‘callback‘)
return HttpResponse(‘%s("我要上鴨王")‘ %(callback,));
function submitJsonp4() {
$.ajax({
url: ‘http://127.0.0.1:9000/xiaokai.html‘,
type: ‘GET‘, //寫post 沒有用 只能發get
dataType: ‘jsonp‘,
jsonp: ‘callback‘, //告訴後臺這個key
jsonpCallback: ‘func‘ //要返回這個函數名 ******
})
}
function func(arg) {
console.log(arg);
}
前端往後端發送數據的幾種方法