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