摘要:簡要理解你才返回對象,你全家都返回對象你指的是響應(yīng)內(nèi)容的第四部分是一門語言,是另一門語言,這門語言抄襲了這門語言就是用請求和響應(yīng)響應(yīng)的第四部分是字符串,可以用語法表示一個(gè)對象,也可以用語法表示一個(gè)數(shù)組,還可以用語法,還可以用語法,還可以用語
簡要理解 AJAX
你才返回對象,你全家都返回對象("你"指的是響應(yīng)內(nèi)容的第四部分)
JS 是一門語言,JSON 是另一門語言,JSON 這門語言抄襲了 JS這門語言
AJAX 就是用 JS set 請求和get 響應(yīng)
響應(yīng)的第四部分是字符串,可以用 JSON 語法表示一個(gè)對象,也可以用 JSON 語法表示一個(gè)數(shù)組,還可以用 XML 語法,還可以用 HTML 語法,還可以用 CSS 語法,還可以用 JS 語法,還可以用我自創(chuàng)的語法
如何發(fā)請求?用 form 可以發(fā)請求,但是會(huì)刷新頁面或新開頁面
用 a 可以發(fā) get 請求,但是也會(huì)刷新頁面或新開頁面
用 img 可以發(fā) get 請求,但是只能以圖片的形式展示
用 link 可以發(fā) get 請求,但是只能以 CSS、favicon 的形式展示
用 script 可以發(fā) get 請求,但是只能以腳本的形式運(yùn)行(就是 JSONP 的實(shí)現(xiàn)原理)
有沒有什么方式可以實(shí)現(xiàn)
get、post、put、delete 請求都行
想以什么形式展示就以什么形式展示
微軟的突破IE 5 率先在 JS 中引入 ActiveX 對象(API),使得 JS 可以直接發(fā)起 HTTP 請求。
隨后 Mozilla、 Safari、 Opera 也跟進(jìn)(抄襲)了,取名 XMLHttpRequest,并被納入 W3C 規(guī)范
Jesse James Garrett 講如下技術(shù)取名叫做 AJAX:異步的 JavaScript 和 XML
AJAX 技術(shù)包括以下四步:
創(chuàng)建 AJAX 對象, 即 XMLHttpRequest
使用 XMLHttpRequest 發(fā)請求
服務(wù)器返回 XML 格式的字符串
JS 解析 XML,并更新局部頁面
AJAX demohttps://github.com/wojiaofeng...
理解 AJAX學(xué) AJAX 之前,需要知道 HTTP 請求內(nèi)容和 HTTP 響應(yīng)內(nèi)容的四個(gè)部分,如下
問題: 老師的key: alue有許多---的是需要背的嗎?
請求內(nèi)容:
響應(yīng)內(nèi)容:
同時(shí)還要知道怎么在 Chrome 上查看 HTTP request 和 HTTP response
那么,AJAX 是什么呢?我們可以畫出 ” client 和 server “ 的關(guān)系圖:
AJAX 就是在 chrome 通過 XMLHttpRequest 對象, 構(gòu)造(set)HTTP 請求和獲?。╣et)HTTP 響應(yīng)的技術(shù)
那么 AJAX 的具體實(shí)現(xiàn)方法是怎么樣的呢?
JS 設(shè)置(set)任意請求 header
請求內(nèi)容第一部分 request.open("get", "/xxx")
請求內(nèi)容第二部分 request.setRequestHeader("content-type","x-www-form-urlencoded")
請求內(nèi)容第四部分 request.send("a=1&b=2")
JS 獲?。╣et)任意響應(yīng) header
響應(yīng)內(nèi)容第一部分 request.status / request.statusText
響應(yīng)內(nèi)容第二部分 request.getResponseHeader() / request.getAllResponseHeaders()
響應(yīng)內(nèi)容第四部分 request.responseText
如何確定寫的 AJAX 代碼是否正確?將你寫的代碼放到 AJAX demo 的 main.js
第一版:使用原生 js 中的 XMLHttpRequest 實(shí)現(xiàn) ajax
//自己寫的第一版 myButton.addEventListener("click", function(){ ajax() }) function ajax(){ //相當(dāng)于告訴瀏覽器我要set Http 請求了 var request = new XMLHttpRequest() //對應(yīng) http 請求的第一部分 request.open("post", "/xxx") //對應(yīng) http 請求的第二部分 request.setRequestHeader("name", "rjj") request.setRequestHeader("name", "zzz") //對應(yīng) 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) } } } //對應(yīng) http 請求的第四部分 request.send("xxxxxxxxx") }
第二版:放到函數(shù)內(nèi)
把第一版中的function ajax(){}內(nèi)寫死的內(nèi)容提取出來, 用變量獲取, 代碼如下:
//自己寫的第二版 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){ //調(diào)用 ajax 函數(shù)的成功函數(shù),并且往這個(gè)函數(shù)添加 request.responseText 變量作為第一個(gè)參數(shù) 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("請求失敗了了") }
第三版:更靈活的函數(shù)調(diào)用
第二版的函數(shù)調(diào)用實(shí)在太難用了, 根本不能在實(shí)際中使用, 我能不能改進(jìn)一下?
我能不能像這樣調(diào)用函數(shù)? 注意我可以改變每個(gè) key: value 的位置, 還可以不設(shè)置某個(gè) 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) }
注意:
successFnAA 是參數(shù), 參數(shù)的值是一個(gè)函數(shù), 函數(shù)的內(nèi)容是function(x){console.log(x)}
但是這個(gè)函數(shù)AA沒有執(zhí)行, 他是在 ajax 函數(shù)內(nèi)部執(zhí)行, 并且往函數(shù)AA添加了一個(gè)參數(shù)(request.responseText)
函數(shù)AA叫做 callback 函數(shù)
第四版: 把他放到自制的 jQuery 上
我想把原生的 AJAX 實(shí)現(xiàn)代碼封裝到我自己寫的庫,應(yīng)該怎么辦?
創(chuàng)造一個(gè)對象, 把第三版的 AJAX 函數(shù)掛到這個(gè)對象上即可
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) } }) }) //創(chuàng)造對象 window.jQuery = function(nodeOrSelector){ var nodes = {} return nodes } //將 AJAX 函數(shù)掛到對象上 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 將代碼優(yōu)化(析構(gòu)賦值)
原代碼:
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 代碼優(yōu)化:
let {method, path, header, successFn, failFn, body} = options
再次優(yōu)化:
將上一步的代碼刪除, 復(fù)制{method, path, header, successFn, failFn, body}
放到window.jQuery.ajax = function(AAA){}的AAA處
第六版: 使用 promise 統(tǒng)一成功函數(shù)名和失敗函數(shù)名
如果一個(gè)項(xiàng)目需要使用兩個(gè)不同的庫,那么你就必須去看這個(gè)庫的代碼才能知道如何調(diào)用成功函數(shù)和失敗函數(shù), 所以我們使用 promise 來統(tǒng)一函數(shù)名,調(diào)用這個(gè)庫的時(shí)候就不必考慮成功函數(shù)的名字
記住: return new Promise(function(resolve, reject){})
添加 promise 步驟
在 window.jQuery.ajax 函數(shù)內(nèi)部, 剪切所有代碼
在 window.jQuery.ajax 函數(shù)內(nèi)部,添加return new Promise(function(resolve, reject){AAA})
在AAA區(qū)域復(fù)制代碼
將 successFn 變成 resolve, 將 failFn 變成 reject
使用 promise
將調(diào)用 jQuery.ajax 中的 successFnAA 和 failFn 及其參數(shù)內(nèi)容刪除
在jQuery.ajax()之后添加.then,其中第一個(gè)參數(shù)表示成功函數(shù), 第二個(gè)參數(shù)表是失敗函數(shù)
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) }) }JSON —— 一門新語言
http://json.org
同源策略只有 協(xié)議+端口+域名 一模一樣才允許發(fā) AJAX 請求
一模一樣一模一樣一模一樣一模一樣一模一樣一模一樣一模一樣一模一樣
http://baidu.com?可以向?http://www.baidu.com?發(fā) AJAX 請求嗎 no
http://baidu.com:80?可以向?http://baidu.com:81?發(fā) AJAX 請求嗎 no
瀏覽器必須保證
只有 協(xié)議+端口+域名 一模一樣才允許發(fā) AJAX 請求
CORS 可以告訴瀏覽器,我倆一家的,別阻止他
突破同源策略 === 跨域
Cross-Origin Resource Sharing
C O 資源R S
A網(wǎng)站的前端程序員打電話告訴B網(wǎng)站的后端程序員A前: 我想和你的網(wǎng)站進(jìn)行交互, 你同意嗎?
B后: 我同意
然后B后端程序員就在后臺(tái)代碼(響應(yīng)內(nèi)容)寫上這一句代碼:
response.setHeader("Access-Control-Allow-Origin", "http://A.com:8001"), 網(wǎng)站是A網(wǎng)站的前端程序員告訴給B后端
這就是 CORS 跨域
我的 github 博客地址: https://github.com/wojiaofeng...
覺得好的可以 start ,O(∩_∩)O謝謝
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/92568.html
摘要:簡要理解你才返回對象,你全家都返回對象你指的是響應(yīng)內(nèi)容的第四部分是一門語言,是另一門語言,這門語言抄襲了這門語言就是用請求和響應(yīng)響應(yīng)的第四部分是字符串,可以用語法表示一個(gè)對象,也可以用語法表示一個(gè)數(shù)組,還可以用語法,還可以用語法,還可以用語 簡要理解 AJAX 你才返回對象,你全家都返回對象(你指的是響應(yīng)內(nèi)容的第四部分) JS 是一門語言,JSON 是另一門語言,JSON 這門語言抄...
摘要:編碼我們發(fā)現(xiàn),中有時(shí)候存在中文,這是就需要對進(jìn)行編碼??梢韵葘⒅形霓D(zhuǎn)換成編碼,然后使用方法對參數(shù)進(jìn)行編碼后傳遞。 本文檔對日常學(xué)習(xí)中用 python 做數(shù)據(jù)爬取時(shí)所遇到的一些問題做簡要記錄,以便日后查閱,部分問題可能因?yàn)檎J(rèn)識(shí)不到位會(huì)存在一些誤解,敬請告知,萬分感謝,共同進(jìn)步。 估算網(wǎng)站規(guī)模 該小節(jié)主要針對于整站爬取的情況。爬取整站之前,肯定是要先對一個(gè)網(wǎng)站的規(guī)模進(jìn)行估計(jì)。這是可以使用g...
摘要:當(dāng)引擎開始執(zhí)行一個(gè)函數(shù)比如回調(diào)函數(shù)時(shí),它就會(huì)把這個(gè)函數(shù)執(zhí)行完,也就是說只有執(zhí)行完這段代碼才會(huì)繼續(xù)執(zhí)行后面的代碼。當(dāng)條件允許時(shí),回調(diào)函數(shù)就會(huì)被運(yùn)行?,F(xiàn)在,返回去執(zhí)行注冊的那個(gè)回調(diào)函數(shù)。 原文地址:http://blog.getify.com/promis... 在微博上看到有人分享LabJS作者寫的關(guān)于Promise的博客,看了下覺得寫得很好,分五個(gè)部分講解了Promise的來龍去脈。從...
摘要:在有了基礎(chǔ)之后,進(jìn)一步學(xué)習(xí)內(nèi)容包括框架。前端學(xué)習(xí)交流群禁止閑聊,非喜勿進(jìn)。代碼提交前必須做的三個(gè)事情檢查所有變更跑一邊單元測試手動(dòng)運(yùn)行一遍所有 網(wǎng)站開發(fā)開發(fā)大致分為前端和后端,前端主要負(fù)責(zé)實(shí)現(xiàn)視覺和交互效果,以及與服務(wù)器通信,完成業(yè)務(wù)邏輯。其核心價(jià)值在于對用戶體驗(yàn)的追求??梢园慈缦滤悸穼W(xué)習(xí)系統(tǒng)學(xué)習(xí): 基礎(chǔ)知識(shí): html + css 這部分建議在?w3school 在線教程上學(xué)習(xí),邊...
閱讀 2967·2021-11-24 09:39
閱讀 3643·2021-11-22 13:54
閱讀 3443·2021-11-16 11:45
閱讀 2483·2021-09-09 09:33
閱讀 3229·2019-08-30 15:55
閱讀 1317·2019-08-29 15:40
閱讀 951·2019-08-29 15:19
閱讀 3443·2019-08-29 15:14