1.ajax 是什么:
AJAX是異步的JavaScript和XML(Asynchronous JavaScript And XML)汁尺。簡(jiǎn)單點(diǎn)說,就是使用 XMLHttpRequest對(duì)象與服務(wù)器通信徒河。 它可以使用JSON系馆,XML,HTML和文本等多種格式發(fā)送和接收顽照。AJAX最吸引人的就是它的“異步”特性由蘑,也就是說他可以在不重新刷新頁面的情況下與服務(wù)器通信,交換數(shù)據(jù)代兵,更新頁面尼酿。
你可以使用AJAX最主要的兩個(gè)特性做下列事:
- 在不重新加載頁面的情況下發(fā)送請(qǐng)求給服務(wù)器。
- 接受并使用從服務(wù)器發(fā)來的數(shù)據(jù)植影。
2.原生js ajax請(qǐng)求步驟:
Step 1 – 怎樣發(fā)送http請(qǐng)求
var httpAjax = new XMLHttpRequest();
//規(guī)定請(qǐng)求的類型裳擎、URL 以及是否異步處理請(qǐng)求。
ajax.open('GET',url,true);
注意:
a.open() 的第一個(gè)參數(shù)是HTTP請(qǐng)求方法 - 有GET思币,POST鹿响,HEAD以及服務(wù)器支持的其他方法。 保證這些方法一定要是大寫字母谷饿,否則其他一些瀏覽器(比如FireFox)可能無法處理這個(gè)請(qǐng)求惶我。
b.第三個(gè)參數(shù)是可選的,用于設(shè)置請(qǐng)求是否是異步的博投。如果設(shè)為 true (默認(rèn)設(shè)置)绸贡,JavaScript執(zhí)行會(huì)持續(xù),并且在服務(wù)器還沒有響應(yīng)的情況下與頁面進(jìn)行交互
c.如果你使用 POST 數(shù)據(jù)贬堵,那就需要設(shè)置請(qǐng)求的MIME類型恃轩。比如,在調(diào)用 send() 方法獲取表單數(shù)據(jù)前要有下面這個(gè):
httpRequest.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
Step 2 – 處理服務(wù)器響應(yīng)
//接受服務(wù)器響應(yīng)數(shù)據(jù)
在發(fā)送請(qǐng)求時(shí)黎做,你提供的JavaScript函數(shù)名負(fù)責(zé)處理響應(yīng):
httpRequest.onreadystatechange = nameOfTheFunction;
這個(gè)函數(shù)應(yīng)該做什么叉跛?首先,函數(shù)要檢查請(qǐng)求的狀態(tài)蒸殿。如果狀態(tài)的值是 XMLHttpRequest.DONE (對(duì)應(yīng)的值是4)筷厘,意味著服務(wù)器響應(yīng)收到了并且是沒問題的鸣峭,然后就可以繼續(xù)執(zhí)行。
if (httpRequest.readyState === XMLHttpRequest.DONE) {
// Everything is good, the response was received.
} else {
// Not ready yet.
}
全部readyState狀態(tài)值都在 XMLHTTPRequest.readyState酥艳,如下也是:
- 0 (未初始化) or (請(qǐng)求還未初始化)
- 1 (正在加載) or (已建立服務(wù)器鏈接)
- 2 (加載成功) or (請(qǐng)求已接受)
- 3 (交互) or (正在處理請(qǐng)求)
- 4 (完成) or (請(qǐng)求已完成并且響應(yīng)已準(zhǔn)備好)
Step 3 – 業(yè)務(wù)處理邏輯
通過檢查響應(yīng)碼 200 OK 區(qū)別對(duì)待成功和不成功的AJAX調(diào)用摊溶。
其余狀態(tài)碼詳細(xì)參考:http://www.runoob.com/http/http-status-codes.html
if (httpRequest.status === 200) {
// Perfect!
} else {
// There was a problem with the request.
// For example, the response may have a 404 (Not Found)
// or 500 (Internal Server Error) response code.
}
在檢查完請(qǐng)求狀態(tài)和HTTP響應(yīng)碼后, 你就可以用服務(wù)器返回的數(shù)據(jù)做任何你想做的了充石。你有兩個(gè)方法去訪問這些數(shù)據(jù):
- httpRequest.responseText – 服務(wù)器以文本字符的形式返回
- httpRequest.responseXML – 以 XMLDocument 對(duì)象方式返回莫换,之后就可以使用JavaScript來處理
3.跨域問題:
a.什么是跨域?
不同源會(huì)造成跨域,哪些是不同源:
a.跨域解決方案骤铃?
JSONP 是 JSON with padding(填充式 JSON 或參數(shù)式 JSON)的簡(jiǎn)寫拉岁。
JSONP實(shí)現(xiàn)跨域請(qǐng)求的原理簡(jiǎn)單的說,就是動(dòng)態(tài)創(chuàng)建<script>標(biāo)簽惰爬,然后利用<script>的src 不受同源策略約束來跨域獲取數(shù)據(jù)喊暖。
JSONP 由兩部分組成:回調(diào)函數(shù)和數(shù)據(jù)∷呵疲回調(diào)函數(shù)是當(dāng)響應(yīng)到來時(shí)應(yīng)該在頁面中調(diào)用的函數(shù)陵叽。回調(diào)函數(shù)的名字一般是在請(qǐng)求中指定的丛版。而數(shù)據(jù)就是傳入回調(diào)函數(shù)中的 JSON 數(shù)據(jù)巩掺。
動(dòng)態(tài)創(chuàng)建<script>標(biāo)簽,設(shè)置其src硼婿,回調(diào)函數(shù)在src中設(shè)置:
var script = document.createElement("script");
script.src = "https://api.douban.com/v2/book/search?q=javascript&count=1&callback=handleResponse";
document.body.insertBefore(script, document.body.firstChild);
在頁面中锌半,返回的JSON作為參數(shù)傳入回調(diào)函數(shù)中禽车,我們通過回調(diào)函數(shù)來來操作數(shù)據(jù)寇漫。
function handleResponse(response){ // 對(duì)response數(shù)據(jù)進(jìn)行操作代碼 }
了解了JSONP的基本使用方法,我們?cè)趯?shí)現(xiàn)上面通過ajax調(diào)用豆瓣接口的需求殉摔,實(shí)現(xiàn)代碼如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>JSONP實(shí)現(xiàn)跨域2</title>
</head>
<body>
<div id="mydiv">
<button id="btn">點(diǎn)擊</button>
</div>
</body>
<script type="text/javascript">
function handleResponse(response){
console.log(response);
}
</script>
<script type="text/javascript">
window.onload = function() {
var oBtn = document.getElementById('btn');
oBtn.onclick = function() {
var script = document.createElement("script");
script.src = "https://api.douban.com/v2/book/search?q=javascript&count=1&callback=handleResponse";
document.body.insertBefore(script, document.body.firstChild);
};
};
</script>
</html>
在控制臺(tái)州胳,我們可以查看到返回的response數(shù)據(jù)格式為JSON對(duì)象格式的,具體需要取出哪些參數(shù)逸月,可以根據(jù)自己的需要:
JSONP目前還是比較流行的跨域方式栓撞,雖然JSONP使用起來方便,但是也存在一些問題:
首先碗硬, JSONP 是從其他域中加載代碼執(zhí)行瓤湘。如果其他域不安全,很可能會(huì)在響應(yīng)中夾帶一些惡意代碼恩尾,而此時(shí)除了完全放棄 JSONP 調(diào)用之外弛说,沒有辦法追究。因此在使用不是你自己運(yùn)維的 Web 服務(wù)時(shí)翰意,一定得保證它安全可靠木人。
其次信柿,要確定 JSONP 請(qǐng)求是否失敗并不容易。雖然 HTML5 給<script>元素新增了一個(gè) onerror事件處理程序醒第,但目前還沒有得到任何瀏覽器支持渔嚷。為此,開發(fā)人員不得不使用計(jì)時(shí)器檢測(cè)指定時(shí)間內(nèi)是否接收到了響應(yīng)稠曼。
b:CORS:跨域資源共享
- 原理:服務(wù)器設(shè)置Access-Control-Allow-OriginHTTP響應(yīng)頭之后形病,瀏覽器將會(huì)允許跨域請(qǐng)求
- 限制:瀏覽器需要支持HTML5,可以支持POST霞幅,PUT等方法兼容ie9以上
需要后臺(tái)設(shè)置
Access-Control-Allow-Origin: * //允許所有域名訪問窒朋,或者
Access-Control-Allow-Origin: http://a.com //只允許所有域名訪問
c:代理,讓跨域變成同域 比如nginx
使用Nginx作為反向代理服務(wù)器蝗岖。在使用Nginx作為代理服務(wù)器侥猩,并在配置中對(duì)應(yīng)的location下添加上如下的設(shè)置:
- add_header 'Access-Control-Allow-Origin' '*';
- add_header 'Access-Control-Allow-Credentials' 'true';
通過這兩個(gè)配置,前端就可以跨域訪問數(shù)據(jù)接口了