一、HTTP請求相關
1、http請求包含以下七個步驟:
1.建立TCP連接
2.web瀏覽器向服務器發送請求命令
3.web瀏覽器發送請求頭信息
4.web服務器應答
5.web服務器發送應答頭信息
6.web服務器向瀏覽器發送數據
7.web服務器關閉TCP連接
2.http請求一般由四部分組成(區分應答)
1.請求的方法,一般是GET或POST請求
2.請求的URL,就是請求的地址
3.請求頭,包含一些客戶端環境信息,身份驗證信息
4.請求體,包含客戶提交的查詢字符串信息,表單信息等。
3.GET和POST請求的區別:
GET:一般用於獲取信息
GET請求會將請求的信息以字符串的形式加載頁面的URL中,所以該方法是不安全的。
有數量的限制,在2000個字符串
POST:一般用於修改服務器上的資源,比如增刪改,當然也具備get請求的功能。
沒有數量限制。
4.一個HTTP響應一般由三部分組成
1.一個數字和文字組成的狀態碼,用來顯示請求成功或失敗。狀態碼參考文末圖片
2.響應頭,響應頭和請求頭一樣也包含許多有用的信息,比如服務器類型,日期時間,內容類型和長度等。
3.響應體,即響應正文
二、XMLHttpRequest對象
1.創建該對象使用new關鍵字來創建一個XMLHTTPRequest對象。
2.方法:
1. open(method,url,async)方法:
使用該方法後不會立即發送請求,而是定義了請求的發送方式,地址,是否異步
參數:method=》請求方式,比如GET或POST
url=》 請求地址
async=》 請求是否異步執行,默認爲true,false爲同步
2. send(string)方法:
使用send方法後就會想服務器發送請求,參數是請求的主體,不一定是一個字符串,也可以是一個FormData對象。
3. setRequestHeader(參數)方法,對於GET請求無效
該方法定義了請求信息以什麼樣的編碼方式傳遞,有三個方式
- 1. application/x-www-form-urlencoded(默認)
- 2.text/plain
- 3.multipart/form-data
- setRequestHeader('content-type':'application/x-www-form-urlencoded')這種格式
4.abort()方法,用於取消當前響應,關閉連接並結束任何未決的網絡活動。
就是說該方法會將XML的readyState變爲0的狀態。
5.getAllResponseHeaders(),把HTTP未解析的響應頭作爲字符串返回。
當readyState小於3時,會返回null。否則,會返回所有的服務器發送的響應頭
6.getResponseHeader(),返回指定的HTTP響應頭的值。
其參數是要返回的 HTTP 響應頭部的名稱
3.屬性
1.readyState,HTTP 請求的狀態.當一個 XMLHttpRequest 初次創建時,這個屬性的值從 0 開始,直到接收到完整的 HTTP 響應,這個值增加到 4。
各個參數代表的含義:
0.XML對象被創建成功
1.open方法調用,但send方法未調用,請求還沒發送
2.send方法也以調用,請求發送出去了
3.web瀏覽器接收到響應頭信息,開始接收響應體但未完成
4.完全接收到響應體
2.responseText,代表瀏覽器接收到的響應體,但不包含頭信息。
當readyState爲4時,該屬性就包含了響應體的全部信息。
響應體一般是一個JSON對象,一般用JSON.parse(XML.responseText)方法轉化爲js對象
那通常要確認瀏覽器已經收到了響應體,一般是做兩層判斷,
var XML = new XMLHttpRequest();
if(XML.readyState === 4){
if(XML.status === 200){
.....
}
}
就是狀態碼也返回200,纔去執行相關操作
3.status,就是狀態碼
4.事件
onReadyStatechange,當readyState屬性值改變的時候會調用該事件。
三、jQuery中的AJAX
jQuery已經封裝好了對AJAX請求的方法,像下面這樣
$.ajax({
type:'POST',
url:'',
data:{},
dataType:'',
success:function(data){},
error:function(XML){}
})
解釋一下,type和url很清楚了
data:是一個對象,連同請求一起發送到服務器的數據,get請求一般可以不指定。
dataType:期望收到的數據的格式,一般是JSON,不過不寫的話JQ會只能的去判斷
success:請求成功後執行的回調函數,參數是返回的數據,以及包含服務器的響應值等等
error:請求失敗執行的回調函數,傳入XML對象
四、跨域
一個地址由http(協議)//www(子域名).baidu(主域名):80(端口號)/server.php(請求資源地址)
來組成。
那隻要前臺請求是與當前的地址的協議,子域名,主域名,端口號任意一個不相同,都算作跨域。
JavaScript出於安全方面的考慮,不允許調用其他頁面的對象,就是說不能跨域請求資源。
如何解決跨域問題呢?
一般由以下方法:
1.
比如www.beijing.com要請求上海服務器www.shanghai.com的資源,
可以通過代理,由後臺操作,北京服務器先向上海服務器請求完資源,然後前臺訪問北京服務器加載該資源
2.JSONP
該方法只支持GET請求實現跨服,因爲該方式會將請求的數據放在url中。
具體實現的原理:
在HTML標籤中,有src屬性的標籤通常都擁有跨域的能力,比如image,script,ifram。
簡單來說就是,在js中規定一個回調函數,用來接收數據,然後創建一個script標籤,src屬性爲接口地址。
最後將script標籤返回來的內容是一個執行函數,函數名爲上述的回調函數名,將要請求的數據當做參數傳入。
具體代碼想這樣:
var getData(data){
console.log(data)
}
var script = document.createElement('script');
var url = '跨域的地址';
script.setAttribute('src',url);'
document.body.appendChild(src);
3.window.name + iframe跨域獲取數據
基本原理:比如在一個index.html的頁面下,新建一個<iframe>標籤。每一個iframe標籤都有屬於自己的window.name屬性(也就是該iframe的contentWindow的name值),並且該值不會隨着iframe的重定向而改變,這樣就可以將數據放到上面,然後再取了。
具體代碼:
<script type="text/javascript">
function crossDomain(url, fn) {
iframe = document.createElement('iframe');
iframe.style.display = 'none';
var state = 0;
iframe.onload = function() {
if(state === 1) {
fn(iframe.contentWindow.name);
iframe.contentWindow.document.write('');
iframe.contentWindow.close();
document.body.removeChild(iframe);
} else if(state === 0) {
state = 1;
iframe.contentWindow.location = 'http://localhost:81/cross-domain/proxy.html';
}
};
//解釋一下,當第一次指定iframe.src的地址爲跨域的服務器地址的時候,iframe.contentWindow.name服務器已經傳遞數據給到了該值,這時候調用任務隊列的onload函數,這時state ===0;然後將iframe重定向至一個同源地址,改變state===1。而此前服務器傳過來的數據,也就是ifra.contentWindow.name是不會變的,再次加載onload的時候,就可以去操作iframe取得數據
iframe.src = url;
document.body.appendChild(iframe);
}
// 調用
// 服務器地址
var url = 'http://localhost:8080/data.php';
crossDomain(url, function(data) { // 處理數據 data就是window.name的值(string)
var data = JSON.parse(iframe.contentWindow.name);
console.log(data);
});
</script>
4.location.hash + iframe 跨域請求獲取數據
原理:這個跟window.name + iframe 是差不多的。只不過該方法是將服務器傳過來的數據放在了iframe.contentWindow.location.hash屬性上。
代碼實例:
<script type="text/javascript">
function getData(url, fn) {
var iframe = document.createElement('iframe');
iframe.style.display = 'none';
iframe.src = url;
iframe.onload = function() {
fn(iframe.contentWindow.location.hash.substring(1));
window.location.hash = '';
document.body.removeChild(iframe);
};
document.body.appendChild(iframe);
}
// get data from server
var url = 'http://localhost:8080/data.php';
getData(url, function(data) {
var jsondata = JSON.parse(data);
console.log(jsondata.name + ' ' + jsondata.age);
});
</script>
5.postMessage方法
基本原理:也是利用iframe display:none的方式,向其他域傳送數據。
語法:postMessage('data',url);第一個參數是要傳的數據,一般以字符串形式。第二個是跨域的地址。
代碼實例:
比如在a.com頁面向b.com頁面傳送數據
那麼要在a頁面創建一個iframe,src指向b.html
<iframe id="iframe" display:none src=http://b.com>
在script中:
獲取到iframe節點
var iframe = document.getElementById('iframe');
iframe.postMessage('我是來自a頁面的數據','http://b.com');
這樣就把數據發送給b頁面了。但是在b頁面中還要定義一個函數來接收該數據,
因此,在b.html中使用onMessage事件來監聽數據的接收
window.addEventListener('message',function(event){
//爲了安全起見要判斷一下消息的來源
console.log(event.source) //bwindow 就是b頁面的window對象,或者是a頁面iframe的contenWindow
console.log(event.origin) //http://a.com
console.log(event.data) //接收的數據
})
6.WebSocket
使用WebSocket方式,不僅可以由客戶端發起請求,還可以從服務器端發起。且不受同源策略的限制。
使用起來也簡單,舉個例子
var ws = new WebSocket("wss://echo.websocket.org"); //新建一個WebSocket對象,傳入跨域請求的地址
ws.onopen = function(evt) {
console.log("Connection open ...");
ws.send("Hello WebSockets!");
};
ws.onmessage = function(evt) {
console.log( "Received Message: " + evt.data);
ws.close();
};
ws.onclose = function(evt) {
console.log("Connection closed.");
};
一些簡單的WebSocket對象的屬性和方法
*readyState返回WebSocket對象的當前狀態,有四種情況:
0 表示正在連接;1 表示連接成功; 2 表示正在關閉連接; 3 表示連接已經關閉
*onopen 用於指定連接成功後的回調函數,一般在該回調裏面發送數據。
*onclose 用於指定連接關閉後的回調函數
*onmessage 用於指定接收到服務器數據後的回調函數,一般會在該回調裏關閉連接
*onerror 用於報錯時的回調函數
*send()方法,用於發送數據
*close()方法,用於關閉連接
7.CORS