固然不夠,這是一個小垃圾本身整理來看的筆記javascript
張三丰:「無忌,我教你的ajax還記得多少?」 張無忌:「回太師傅,我只記得一大半」 張三丰:「那,如今呢?」 張無忌:「已經剩下一小半了」 張三丰:「那,如今呢?」 張無忌:「我已經把全部的全忘記了!」 張三丰:「你丫的趕忙滾去複習…」php
o(╥﹏╥)o好的師傅,是的師傅css
http
協議 是文本傳輸協議html規定了瀏覽器和服務器之間的通訊規則前端
`HTTP1協議規定了請求和響應的標準java
http的特色jquery
GET、HEAD、POST
。每種方法規定了客戶與服務器聯繫的類型不一樣。因爲HTTP協議簡單,使得HTTP服務器的程序規模小,於是通訊速度很快。HTTP
容許傳輸任意類型的數據對象。正在傳輸的類型由Content-Type
加以標記。HTTP
協議是無狀態協議。無狀態是指協議對於事務處理沒有記憶能力。缺乏狀態意味着若是後續處理須要前面的信息,則它必須重傳,這樣可能致使每次鏈接傳送的數據量增大。另外一方面,在服務器不須要先前信息時它的應答就較快。B/S
及C/S
模式。get
請求的請求報文//---請求行
// /mydata/01.php?username=pp&password=123456 請求路徑+參數(注意點)
// HTTP/1.1 HTTP的版本號
GET /day02/01.php?username=pp&password=123456 HTTP/1.1
//---請求頭
Host: www.study.com
Connection: keep-alive
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.96 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,`*/*`;q=0.8
Accept-Encoding: gzip, deflate, sdch
Accept-Language: zh-CN,zh;q=0.8,en;q=0.6
//---請求體
//get請求沒有請求體,須要傳遞的數據會拼接到請求行中
複製代碼
post
請求的請求報文//---請求行
POST /day02/01.php HTTP/1.1
//---請求頭
Host: www.study.com
Connection: keep-alive
//傳遞的參數的長度。
Content-Length: 29
Cache-Control: max-age=0
Origin: http://www.study.com
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.96 Safari/537.36
//內容類型:表單數據,若是是post請求,必須指定這個屬性。
Content-Type: application/x-www-form-urlencoded
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,`*/*`;q=0.8
Referer: http://www.study.com/day02/01-login.html
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.8,en;q=0.6
//---請求體
username=pp&password=123456
複製代碼
get
沒有請求體所需的參數頭都拼接到地址欄了post
有請求體,請求體內是post
要提交的數據//---------------------狀態行(響應行)-------------------------------
//HTTP/1.1 HTTP版本
//200 響應的狀態
//200表示成功
//304表示文檔未修改
//404表示找不到資源
//500表示服務端錯誤
HTTP/1.1 200 OK
//----------------------響應頭-----------------------------------------------
Date: Thu, 22 Jun 2017 16:51:22 GMT
Server: Apache/2.4.23 (Win32) OpenSSL/1.0.2j PHP/5.4.45
X-Powered-By: PHP/5.4.45
Content-Length: 18
Keep-Alive: timeout=5, max=100
Connection: Keep-Alive
//內容類型,告訴瀏覽器該如何解析響應結果
Content-Type: text/html;charset=utf-8
//-----------------------響應體------------------------------------------------
hello world
複製代碼
問個簡單的問題,什麼是愛情...咳咳咳,不什麼是ajaxweb
ajax
不是一種新的語言ajax
本質上是在HTTP協議的基礎上以異步的方式與服務器進行通訊同步渲染須要先獲取數據,可是若是數據獲取的速度慢了,就會影響整個頁面的渲染速度,數據也沒法更新面試
form 表單獲取數據 |
ajax 獲取數據 |
---|---|
頁面會跳轉 | 頁面不會跳轉,能夠局部刷新 |
只可以發送同步的請求 | 能夠發送異步請求 |
用html 書寫 |
用js 書寫 |
ajax
能夠異步的獲取數據ajax那麼請問什麼是異步
同步與異步
網頁異步的應用
怎麼實現異步
XMLHttpRequest
能夠以異步的請求數據處理程序,可實現對網頁的部分更新,不會刷新頁面
那麼問題又又又來了什麼是XMLHttpRequest
什麼是XMLHttpRequest
對象來着,百度使我快樂
XMLHttpRequest
對象用於在後臺與服務器交換數據。XMLHttpRequest
對象是開發者的夢想,由於您可以:
注意全部現代的瀏覽器都支持 XMLHttpRequest
對象。
XMLHttpRequest
以異步的方式發送HTTP請求,所以在發送請求時,同樣須要遵循HTTP協議。
使用
XMLHttpRequest
用異步的方式發送HTTP
請求,所以在發送請求時,同樣須要遵循HTTP
//1. 建立一個XMLHttpRequest對象
var xhr = new XMLHttpRequest();
//2. 設置請求行
// 第一個參數:請求方式 get/post
// 第二個參數:請求的地址 須要在url後面拼上參數列表
// 第三個參數: 是否異步請求,默認是true true就是異步,false是同步
xhr.open("get", "01.php?name=haha");
//3. 設置請求頭(get不用設置)
//請求頭中能夠設置Content-Type,用以說明請求主體的內容是如何編碼
//get請求時沒有請求體,無需設置請求頭
//xhr.setRequestHeader()
//4. 設置請求體
//get請求的請求體爲空,由於參數列表拼接到url後面了
xhr.send(null);
複製代碼
注意點 :
get
請求,設置請求行時,須要把參數列表拼接到url
後面get
請求不用設置請求頭, 不用說明請求主體的編碼方式get
請求的請求體爲null
//1. 建立一個XMLHttpRequest對象
var xhr = new XMLHttpRequest();
// 2. 設置請求行 post請求的參數列表在請求體
xhr.open("post", "02.php");
// 3. 設置請求頭, post 請求必需要設置 content-type, 標記請求體內容的解析方式, 否則後端沒法解析獲取數據
xhr.setRequestHeader( "content-type", "application/x-www-form-urlencoded" );
//在請求發送過程當中會對數據進行序列化處理,以鍵值對形式?key1=value1&key2=value2的方式發送到服務器
// 4. 設置請求體
xhr.send( "name=zs&age=18" );
複製代碼
注意點 :
post
請求, 設置請求行時, 不拼接參數列表post
必須設置請求頭中的content-type
爲application/x-www-form-urlencoded
, 標記請求體解析方式post
請求須要將參數列表設置到請求體中readyState
:記錄了XMLHttpRequest對象的當前狀態
readyState有五種可能的值:
xhr.readyState = 0時,UNSENT open還沒有調用
xhr.readyState = 1時,OPENED open已調用
xhr.readyState = 2時,HEADERS_RECEIVED 接收到響應頭信息
xhr.readyState = 3時,LOADING 接收到響應主體
xhr.readyState = 4時,DONE 響應完成
不用記憶狀態,只須要了解有狀態變化這個概念
複製代碼
HTTP響應分爲3個部分,狀態行、響應頭、響應體。
注意:
onreadystatechange
只會被觸發3次//給xhr註冊一個onreadystatechange事件,當xhr的狀態發生狀態發生改變時,會觸發這個事件。
//只會被觸發3次(2,3,4)
xhr.onreadystatechange = function () {
if(xhr.readyState == 4){
//1. 獲取狀態行
console.log("狀態行:"+xhr.status);
//2. 獲取響應頭
console.log("全部的響應頭:"+xhr.getAllResponseHeaders());
console.log("指定響應頭:"+xhr.getResponseHeader("content-type"));
//3. 獲取響應體
console.log(xhr.responseText);
}
}
複製代碼
瀏覽器端只是負責用戶的交互和數據的收集以及展現,真正的數據都是存儲在服務器端的。
咱們如今經過ajax的確能夠返回一些簡單的數據(一個字符串),
可是在實際開發過程當中,確定會會設計到大量的複雜類型的數據傳輸,
好比數組、對象等,可是每一個編程語言的語法都不同。
所以咱們會採用經過的數據交換格式(XML、JSON)來進行數據的交互。
複製代碼
什麼是XML
XML
指可擴展標記語言(EXtensible Markup Language
)XML
是一種標記語言,很相似 HTML
XML
的設計宗旨是傳輸數據,而非顯示數據XML
標籤沒有被預約義。您須要自行定義標籤。語法規範
HTML
同樣<?xml version="1.0" encoding="utf-8" ?>
<students>
<student >
<name>張三</name>
<age>18</age>
<gender>男</gender>
<desc>路人甲</desc>
</student>
<student>
<name>李四</name>
<age>20</age>
<gender>男</gender>
<desc>路人乙</desc>
</student>
</students>
複製代碼
php獲取xml文件的內容
// 注意: 若是須要返回 xml 數據, 須要將 content-type 改爲 text/xml, 否則瀏覽器以 text/html 解析
header( 'content-type:text/xml;charset=utf-8' );
// file_get_content 用於獲取文件的內容
// 參數: 文件的路徑
$result = file_get_content( "data.xml" );
echo $result;
複製代碼
js解析xml
//獲取服務端返回的xml數據,須要使用xhr.responseXML,這是一個document對象,可使用DOM中的方法查找元素。
var data = xhr.responseXML;
//獲取全部的學生
var students = data.querySelectorAll("student");
複製代碼
缺點:太麻煩
JSON(JavaScript Object Notation, JS 對象標記) 是一種輕量級的數據交換格式。它基於 ECMAScript 規範,採用獨立於編程語言的文本格式來存儲和表示數據。
var obj = {a: 'Hello', b: 'World'}; //這是一個js對象
var obj = {"a": "Hello", "b": "World"}; //這是一個json對象
// 這是一個 JSON 字符串,本質是一個字符串
var json = '{"a": "Hello", "b": "World"}';//這是一個json字符串
{"name": "zs"}
[{"name": "zs"},{"name":"ls"}]
複製代碼
JSON
數據在不一樣語言進行傳輸時,類型爲字符串,不一樣的語言各自也都對應有解析方法,解析完成後就能很方便的使用了
js
處理json
JS
對象 ==> JSON
字符串JSON.stringify(obj)
//obj是一個js對象
var obj = {a: 'Hello', b: 'World'}
//result就變成了一個json字符串了
var result = JSON.stringify(obj);// '{"a": "Hello", "b": "World"}'
複製代碼
JSON
字符串 ==>JS
對象 JSON.parse(str)
//json是一個json字符串
var json = '{"a": "Hello", "b": "World"}';
//obj就變成了一個js對象
var obj = JSON.parse(json);// {a: 'Hello', b: 'World'}
複製代碼
整了半天仍是似懂非懂啊o(╥﹏╥)o
封裝步驟
建立xhr
對象
設置請求行
設置請求頭
設置請求體
監聽響應狀態
獲取響應內容
完整版本
var $ = {
ajax: function (options) {
//若是options參數沒有傳遞,直接返回。
if (!options || typeof options !== "object") {
return;
}
//處理默認參數
//若是參數不是post,那就默認爲get
var type = options.type == "post" ? "post" : "get";
//若是沒有傳url,那就傳當前地址
var url = options.url || location.pathname;
//若是參數不是false,那就默認是true,發異步請求
var async = options.async == false ? false : true;
var params = this.getParams(options.data);
var xhr = new XMLHttpRequest();
//設置請求行
if (type == "get") {
url = url + "?" + params;
}
xhr.open(type, url, async);
//設置請求頭
if (type == "post") {
xhr.setRequestHeader("content-type", "application/x-www-form-urlencoded");
}
//設置請求參數
xhr.send(params);
xhr.onreadystatechange = function () {
if (xhr.readyState == 4) {
if (xhr.status == 200) {
/*根據響應頭的content-type屬性指定方法接收到的內容*/
var contentType = xhr.getResponseHeader('content-type');
var data = null;
if (contentType.indexOf('json') > -1) {
data = JSON.parse(xhr.responseText);
} else if (contentType.indexOf('xml') > -1) {
data = xhr.responseXML;
} else {
data = xhr.responseText;
}
/*執行成功函數*/
options.success && options.success(data);
} else {
options.error && options.error(xhr.responseText);
}
}
}
},
getParams: function (obj) {
//將obj對象轉換成參數
//將對象轉換成參數列表
if (!obj) {
return null;
}
var arr = [];
for (var k in obj) {
arr.push(k + "=" + obj[k]);
}
return arr.join("&");
}
}
複製代碼
jQuery
爲咱們提供了更強大的Ajax封裝,我好像只記得這種而已
參數列表
參數名稱 | 描述 | 取值 | 示例 |
---|---|---|---|
url | 接口地址 | url:"02.php" | |
type | 請求方式 | get/post | type:"get" |
timeout | 超時時間 | 單位毫秒 | timeout:5000 |
dataType | 服務器返回的格式 | json/ xml/text(默認) | dataType:"json" |
data | 發送的請求數據 | 對象 | data:{name:"zs", age:18} |
beforeSend | 調用前的回調函數 | function(){} | beforeSend:function(){ alert(1) } |
success | 成功的回調函數 | function (data) {} | success:function (data) {} |
error | 失敗的回調函數 | function (error) {} | error:function(data) {} |
complete | 完成後的回調函數 | function () {} | complete:function () {} |
使用示例:
$.ajax({
type:"get",//請求類型
url:"02.php",//請求地址
data:{name:"zs", age:18},//請求數據
dataType:"json",//但願接受的數據類型
timeout:5000,//設置超時時間
beforeSend:function () {
//alert("發送前調用");
},
success:function (data) {
//alert("成功時調用");
console.log(data);
},
error:function (error) {
//alert("失敗時調用");
console.log(error);
},
complete:function () {
//alert("請求完成時調用");
}
});
$.get
$.post
複製代碼
1995年,同源政策由 Netscape 公司引入瀏覽器。目前,全部瀏覽器都實行這個政策。 同源策略:最初,它的含義是指,A網頁設置的 Cookie,B網頁不能打開,除非這兩個網頁"同源"。所謂"同源"指的是"三個相同"。
協議相同
域名相同
端口相同
複製代碼
舉例來講,這個網址http://www.example.com/dir/page.html
協議是http://
,
域名是www.example.com
,端口是80
(默認端口能夠省略)。它的同源狀況以下。
http://www.example.com/dir2/other.html:同源
file:///F:/phpStudy/WWW/day01/04-demo/04.html 不一樣源(協議不一樣)
http://v2.www.example.com/dir/other.html:不一樣源(域名不一樣)
http://www.example.com:81/dir/other.html:不一樣源(端口不一樣)
複製代碼
同源政策的目的,是爲了保證用戶信息的安全,防止惡意的網站竊取數據。
隨着互聯網的發展,「同源策略」愈來愈嚴格,目前,若是非同源,如下三種行爲都將收到限制。
1. Cookie、LocalStorage 和 IndexDB 沒法讀取。
2. DOM 沒法得到。
3. AJAX 請求不能發送。
複製代碼
雖然這些限制是頗有必要的,可是也給咱們平常開發帶來很差的影響。好比實際開發過程當中,每每都會把服務器端架設到一臺甚至是一個集羣的服務器中,把客戶端頁面放到另一個單獨的服務器。那麼這時候就會出現不一樣源的狀況,若是咱們知道兩個網站都是安全的話,咱們是但願兩個不一樣源的網站之間能夠相互請求數據的。這就須要使用到跨域 。
JSONP(JSON with Padding)、可用於解決主流瀏覽器的跨域數據訪問的問題。
原理:服務端返回一個定義好的js函數的調用,而且將服務器的數據以該函數參數的形式傳遞過來,這個方法須要先後端配合
script
標籤是不受同源策略的限制的,它能夠載入任意地方的 JavaScript 文件。相似的還有img
和link
標籤
<!--不受同源策略限制的標籤-->
<img src="http://www.api.com/1.jpg" alt="">
<link rel="stylesheet" href="http://www.api.com/1.css">
<script src="http://www.api.com/1.js"></script>
複製代碼
html文件
<script src="http://www.api.com/testjs.php"></script>
複製代碼
原理:其實src的路徑是什麼文件不重要,不管引入js文件仍是php文件,最後返回給瀏覽器的都是字符串,所以咱們script標籤是能夠引入一個php文件的。
php文件
header("content-type:text/html;charset=utf-8");
echo "var a = 118;";
複製代碼
html文件
<script src="http://www.api.com/testjs.php"> </script>
<script> //a打印出來了118 console.log(a); </script>
複製代碼
咱們如今作到了一件事情,從不一樣源的php文件中獲取到了數據
缺點:獲取數據的script標籤必須寫在使用的script標籤的前面,必須保證先有數據才能對數據進行渲染。
php代碼
header("content-type:text/html;charset=utf-8");
$arr = array(
"name"=>"zs",
"age"=>18
);
$result = json_encode($arr);
//這是一段js函數的調用的代碼,$result就是咱們想要的數據
echo "func($result)";
複製代碼
js代碼
<script> function func(data) { console.log(data); } </script>
<script src="http://www.api.com/testjs.php"></script>
複製代碼
缺點:後端必須知道前端聲明的方法的名字,後端才能調用。
php代碼
header("content-type:text/html;charset=utf-8");
$arr = array(
"name"=>"zs",
"age"=>18
);
$result = json_encode($arr);
//這是一段js函數的調用的代碼,$result就是咱們想要的數據
echo $_GET['callback']."($result)"; //fun($result)
複製代碼
javascript代碼
function fun(data) {
console.log(data);
}
var button = document.querySelector("button");
button.onclick = function () {
var script = document.createElement("script");
script.src = "http://www.api.com/testjs.php?callback=fun";
document.body.appendChild(script);
}
複製代碼
jsonp原理你們須要知道,面試中常常會問到,實際工做中不用糾結, 由於jquery已經幫咱們封裝好了,咱們使用起來很是的方便。
jquery
對於jsonp
的封裝注意: jsonp
僅支持get
請求
//使用起來至關的簡單,跟普通的get請求沒有任何的區別,只須要把dataType固定成jsonp便可。
$.ajax({
type:"get",
url:"http://www.Jepson.com/testjs.php",
dataType:"jsonp",
data:{
uname:"zs",
upass:"123456"
},
success:function (info) {
console.log(info);
}
});
複製代碼
XMLHttpRequest是一個javascript內置對象,使得Javascript能夠進行異步的HTTP通訊。2008年2月,就提出了XMLHttpRequest Level 2 草案。
老版本的XMLHttpRequest的缺點:
1. 僅支持傳輸文本數據,沒法傳輸二進制文件,好比圖片視頻等。
2. 傳輸數據時,沒有進度信息,只能提示完成與否。
3. 受到了"同源策略"的限制
複製代碼
新版本的功能:
1. 能夠設置timeout超時時間
2. 可使用formData對象管理表單數據
3. 容許請求不一樣域名下的數據(跨域)
4. 支持上傳二進制文件
5. 能夠獲取數據傳輸的進度信息
複製代碼
注意:咱們如今使用new XMLHttpRequest建立的對象就是2.0對象了,咱們以前學的是1.0的語法,如今學習一些2.0的新特性便可。
xhr.timeout = 3000;//設置超時時間
xhr.ontimeout = function(){
alert("請求超時");
}
複製代碼
formData
對象相似於jquery
的serialize
方法,用於管理表單數據
formData
僅支持post
請求不須要設置請求頭, 瀏覽器會自動檢測幫咱們設置
使用特色:
1. 實例化一個formData對象, new formData(form); form就是表單元素
2. formData對象能夠直接做爲 xhr.send(formData)的參數。注意此時數據是以二進制的形式進行傳輸。
3. formData有一個append方法,能夠添加參數。formData.append("id", "1111");
4. 這種方式只能以post形式傳遞,不須要設置請求頭,瀏覽器會自動爲咱們設置一個合適的請求頭。
複製代碼
代碼示例:
//1. 使用formData必須發送post請求
xhr.open("post", "02-formData.php");
//2. 獲取表單元素
var form = document.querySelector("#myForm");
//3. 建立form對象,能夠直接做爲send的參數。
var formData = new FormData(form);
//4. formData可使用append方法添加參數
formData.append("id", "1111");
//5. 發送,不須要指定請求頭,瀏覽器會自動選擇合適的請求頭
xhr.send(formData);
複製代碼
之前,文件上傳須要藉助表單進行上傳,可是表單上傳是同步的,也就是說文件上傳時,頁面須要提交和刷新,用戶體驗不友好,
xhr2.0
中的formData
對象支持文件的異步上傳。
var formData = new FormData();
//獲取上傳的文件,傳遞到後端
var file = document.getElementById("file").files[0];
formData.append("file", file);
xhr.send(formData);
複製代碼
xhr2.0
還支持獲取上傳文件的進度信息,所以咱們能夠根據進度信息能夠實時的顯示文件的上傳進度。
1. 須要註冊 xhr.upload.onprogress = function(e){} 事件,用於監聽文件上傳的進度.注意:須要在send以前註冊。
2. 上傳的進度信息會存儲事件對象e中
3. e.loaded表示已上傳的大小 e.total表示整個文件的大小 單位是字節
複製代碼
代碼參考:
xhr.upload.onprogress = function (e) {
inner.style.width = (e.loaded/e.total*100).toFixed(2)+"%";
span.innerHTML = (e.loaded/e.total*100).toFixed(2)+"%";
}
xhr.send(formData);
toFixed(2) //保留兩位兩數
複製代碼
新版本的XMLHttpRequest對象,能夠向不一樣域名的服務器發出HTTP請求。這叫作"跨域資源共享"(Cross-origin resource sharing,簡稱CORS)。
跨域資源共享(CORS)的前提
服務器容許跨域的代碼:
//容許全部的域名訪問這個接口
header("Access-Control-Allow-Origin:*");
//容許www.study.com這個域名訪問這個接口
header("Access-Control-Allow-Origin:http://www.study.com");
複製代碼
瀏覽器發送跨域請求
服務器端收到一個跨域請求後,在響應頭中添加Access-Control-Allow-Origin Header
資源權限配置。發送響應
瀏覽器收到響應後,查看是否設置了header('Access-Control-Allow-Origin:請求源域名或者*');
若是當前域已經獲得受權,則將結果返回給JavaScript。不然瀏覽器忽略這次響應。
結論: