用 form 能夠發請求,可是會刷新頁面或新開頁面
用 a 能夠發 get 請求,可是也會刷新頁面或新開頁面
用 img 能夠發 get 請求,可是隻能以圖片的形式展現
用 link 能夠發 get 請求,可是隻能以 CSS、favicon 的形式展現
用 script 能夠發 get 請求,可是隻能以腳本的形式運行(就是 JSONP 的實現原理)前端
有沒有什麼方式能夠實現node
IE 5 率先在 JS 中引入 ActiveX 對象(API),使得 JS 能夠直接發起 HTTP 請求。
隨後 Mozilla、 Safari、 Opera 也跟進(抄襲)了,取名 XMLHttpRequest,並被歸入 W3C 規範git
Jesse James Garrett 講以下技術取名叫作 AJAX:異步的 JavaScript 和 XML程序員
AJAX 技術包括如下四步:github
https://github.com/wojiaofeng...ajax
學 AJAX 以前,須要知道 HTTP 請求內容和 HTTP 響應內容的四個部分,以下chrome
問題: 老師的
key: alue
有許多---的是須要背的嗎?
請求內容:json
響應內容: 後端
同時還要知道怎麼在 Chrome 上查看 HTTP request 和 HTTP response 跨域
那麼,AJAX 是什麼呢?咱們能夠畫出 」 client 和 server 「 的關係圖:
AJAX 就是在 chrome 經過 XMLHttpRequest 對象, 構造(set)HTTP 請求和獲取(get)HTTP 響應的技術
那麼 AJAX 的具體實現方法是怎麼樣的呢?
如何肯定寫的 AJAX 代碼是否正確?將你寫的代碼放到 AJAX demo 的 main.js
初版:使用原生 js 中的 XMLHttpRequest 實現 ajax
//本身寫的初版 myButton.addEventListener('click', function(){ ajax() }) function ajax(){ //至關於告訴瀏覽器我要set Http 請求了 var request = new XMLHttpRequest() //對應 http 請求的第一部分 request.open("post", "/xxx") //對應 http 請求的第二部分 request.setRequestHeader("name", "rjj") request.setRequestHeader("name", "zzz") //對應 http 請求的第三部分,僅僅是爲了便於記憶 request.onreadystatechange = function(){ if(request.readyState === 4){ if(request.status >= 200 && request.status < 300){ console.log("成功") console.log("request.responseText") console.log(request.responseText) }else{ console.log("失敗") console.log(request) } } } //對應 http 請求的第四部分 request.send("xxxxxxxxx") }
第二版:放到函數內
把初版中的function ajax(){}
內寫死的內容提取出來, 用變量獲取, 代碼以下:
//本身寫的第二版 myButton.addEventListener('click', function(){ ajax("post", "/xxx", {name:'rjj', sss:'zxxx'}, fffff, yyyyyy) }) function ajax(method, path, header, successFn, failFn, body){ var request = new XMLHttpRequest() request.open(method, path) for(var key in header){ request.setRequestHeader(key, header[key]) } request.onreadystatechange = function(){ if(request.readyState === 4){ if(request.status >= 200 && request.status < 300){ //調用 ajax 函數的成功函數,而且往這個函數添加 request.responseText 變量做爲第一個參數 successFn.call(undefined, request.responseText) }else{ failFn.call(undefined, request) } } } request.send(body) } function fffff(x){ console.log(x) console.log("請求成功了") } function yyyyyy(x){ console.log(x) console.log("請求失敗了了") }
第三版:更靈活的函數調用
第二版的函數調用實在太難用了, 根本不能在實際中使用, 我能不能改進一下?
我能不能像這樣調用函數? 注意我能夠改變每一個 key: value 的位置, 還能夠不設置某個 key: value
ajax({ method: "post", path: "/xxx", header:{ name:"rjj", test:"rjj111", test2:"rjj2222" } body: "password=xxx", successFn: success, failFn: fail })
myButton.addEventListener('click', function(){ ajax({ method: "post", header:{ name: "xxx", zzz:'xxx', }, successFnAA: function(x){ console.log(x) }, failFnAA: function(x){ console.log(x) }, path: "/xxx", }) }) function ajax(options){ var method = options.method var path = options.path var header = options.header var successFn = options.successFnAA var failFn = options.failFnAA var body = options.body var request = new XMLHttpRequest() request.open(method, path) for(var key in header){ request.setRequestHeader(key, header[key]) } request.onreadystatechange = function(){ if(request.readyState === 4){ if(request.status >= 200 && request.status < 300){ successFn.call(undefined, request.responseText) }else{ failFn.call(undefined, request) } } } request.send(body) }
注意:
function(x){console.log(x)}
第四版: 把他放到自制的 jQuery 上
我想把原生的 AJAX 實現代碼封裝到我本身寫的庫,應該怎麼辦?
創造一個對象, 把第三版的 AJAX 函數掛到這個對象上便可
myButton.addEventListener("click", function(){ $.ajax( { method: "post", path: "/xxx", header:{ name: "xxx", zzz:'xxx', }, successFnAA: function(x){ console.log(x) }, failFnAA: function(x){ console.log(x) } }) }) //創造對象 window.jQuery = function(nodeOrSelector){ var nodes = {} return nodes } //將 AJAX 函數掛到對象上 window.jQuery.ajax = function(options){ var method = options.method var path = options.path var header = options.header var successFn = options.successFnAA var failFn = options.failFnAA var body = options.body var request = new XMLHttpRequest() request.open(method, path) for(var key in header){ request.setRequestHeader(key, header[key]) } request.onreadystatechange = function(){ if(request.readyState === 4){ if(request.status >= 200 && request.status < 300){ successFn.call(undefined, request.responseText) }else{ failFn.call(undefined, request) } } } request.send(body) } //僅僅是簡寫,並不重要 window.$ = window.jQuery
第五版: 使用 ES6 將代碼優化(析構賦值)
原代碼:
var method = options.method var path = options.path var header = options.header var successFn = options.successFn var failFn = options.failFn var body = options.body
使用 ES6 代碼優化:
let {method, path, header, successFn, failFn, body} = options
將上一步的代碼刪除, 複製{method, path, header, successFn, failFn, body}
放到window.jQuery.ajax = function(AAA){}
的AAA處
第六版: 使用 promise 統一成功函數名和失敗函數名
若是一個項目須要使用兩個不一樣的庫,那麼你就必須去看這個庫的代碼才能知道如何調用成功函數和失敗函數, 因此咱們使用 promise 來統一函數名,調用這個庫的時候就沒必要考慮成功函數的名字
記住: return new Promise(function(resolve, reject){})
添加 promise 步驟
return new Promise(function(resolve, reject){AAA})
使用 promise
jQuery.ajax()
以後添加.then
,其中第一個參數表示成功函數, 第二個參數表是失敗函數myButton.addEventListener("click", function() { jQuery.ajax({ method: "post", path: "/xxx", header: { name: "xxx", zzz: 'xxx' } }).then(function () { console.log(1) }, function () { console.log(2) }) }) window.jQuery = function(nodeOrSelector){ var nodes = {} return nodes } window.jQuery.ajax = function(options){ return new Promise(function (resolve, reject) { var method = options.method var path = options.path var header = options.header var body = options.body var request = new XMLHttpRequest() request.open(method, path) for (var key in header) { request.setRequestHeader(key, header[key]) } request.onreadystatechange = function(){ if (request.readyState === 4) { if (request.status >= 200 && request.status < 300) { resolve.call(undefined, request.responseText) } else { reject.call(undefined, request) } } } request.send(body) }) }
只有 協議+端口+域名 如出一轍才容許發 AJAX 請求
如出一轍如出一轍如出一轍如出一轍如出一轍如出一轍如出一轍如出一轍
瀏覽器必須保證
只有 協議+端口+域名 如出一轍才容許發 AJAX 請求
CORS 能夠告訴瀏覽器,我倆一家的,別阻止他
突破同源策略 === 跨域
Cross-Origin Resource Sharing
C O 資源R S
A網站的前端程序員打電話告訴B網站的後端程序員A前: 我想和你的網站進行交互, 你贊成嗎?
B後: 我贊成
而後B後端程序員就在後臺代碼(響應內容)寫上這一句代碼:
response.setHeader("Access-Control-Allow-Origin", "http://A.com:8001")
, 網站是A網站的前端程序員告訴給B後端
這就是 CORS 跨域
個人 github 博客地址: https://github.com/wojiaofeng...以爲好的能夠 start ,O(∩_∩)O謝謝