JSONP生長
了解了JSONP手藝棧后,知道了JSONP是AJAX湧現之前後端交互最好的解決計劃,但它依舊沒解決問題,用JSONP只能發送GET要求,不能發其他要求
form表單能夠發GET要求,也能夠發POST要求,POST要求沒有要求參數,然則會革新頁面或新開頁面
<form action="/xxx" method=get>
<input type="password" name="password">
<input type="submit">
</form>
a標籤能夠發GET要求,會革新頁面或新開頁面
<a id="x" href="/xxx">
<script> //進入頁面就會自動點a標籤
x.click()
</script>
img標籤能夠發GET要求,只能以圖片體式格局展現
let image = document.createElement('img')
img.src = '/xxx'
imgae.onload = () => {}
imgae.onerror = () => {}
link能夠發GET要求,然則只能以CSS、favicon的情勢展現
let link = document.createElement('link')
link.src = '/xxx'
document.head.appendChild(link)
link.onload = () => {}
link.onerror = () => {}
用script能夠發GET要求,然則只能以劇本的情勢運轉
let script = document.createElement('script')
script.src = '/xxx'
document.body.appendChild(script)
script.onload = () => {}
script.onerror = () => {}
有無什麼體式格局能夠完成
- get、post、put、delete要求都行
- 想以什麼情勢展現就以什麼情勢展現
微軟的打破
IE 5 率先在 JS 中引入 ActiveX 對象(API),使得 JS 能夠直接提議 HTTP 要求。
隨後 Mozilla、 Safari、 Opera 也跟進(剽竊)了,取名 XMLHttpRequest,並被歸入 W3C 範例
AJAX
AJAX 全稱 Async Javascript and XML 翻譯成中文:異步的 JavaScript 和 XML
Ajax 手藝的中心是 XMLHttpRequest 對象(簡稱:XHR),能夠在不革新頁面頁面也能獲得新的數據。
滿足下面的前提就是AJAX
- 運用 XMLHttpReques 發要求
- 服務器返回 XML 花樣的字符串
- JS 剖析 XML,並更新部份頁面
XMLHttpRequest 的用法
運用 XMLHttpRequest 三步驟:
- 要用 XMLHttpRequest 組織一個對象
- 挪用 open() 要領
- 挪用 send() 要領
open() 要領吸收三個參數:要求範例,要求 url,是不是運用異步;
send() 要領接收一個參數:要求主體發送的數據。
這個要求是同步的,瀏覽器會比及服務器相應以後繼承實行,相應以後的相干屬性:
responseText:相應主體返回的文本
status:相應的 HTTP 狀況
statusText:相應的 HTTP 狀況申明
在吸收到相應后,應當如許搜檢兩種狀況
let request = new XMLHttpRequest()
request.onreadystatechange = function(e){
if(request.status >= 200 && request.status < 300 || request.status === 304){
console.log(request.responseText)
}else if(request.status >=400){
console.log("錯誤信息:" + request.status)
}
}
request.open('POST','http://jack.com:8889/xxx')
request.send()
大多數情況下,我們運用的是異步要求,才 JS 繼承實行,沒必要守候相應,此時應當搜檢readyState
,這個屬性有5種取值:
值 | 狀況 | 形貌 |
---|---|---|
0 | UNSENT(未翻開) | open()要領還未被挪用 |
1 | OPENED(未發送) | send()要領還未被挪用 |
2 | HEADERS_RECEIVED(以獵取相應頭) | send()要領已被挪用,相應頭和相應狀況已返回 |
3 | LOADING(正在下載相應體) | 相應體下載中;responseText中已獵取部份數據 |
4 | DONE(要求完成) | 全部要求歷程已終了 |
只需readyState
屬性值一變化,就會觸發一次readystatechange
事宜,能夠應用這個事宜來檢測每次狀況變化后的readystate
的屬性值,一般我們只對readystate
值為4
舉行檢測。
let request = new XMLHttpRequest()
request.onreadystatechange = function(e){
if(request.readyState === 4){
if(request.status >= 200 && request.status <= 300){
console.log(request.responseText)
}else if(request.status >=400){
console.log("錯誤信息:" + request.status)
}
}
}
request.open('POST','http://jack.com:8889/xxx')
request.send()
相應返回的requestText
永遠是字符串,初期運用的相符 XML 花樣的字符串,如今運用的是相符 JSON 語法的字符串,前端拿到后能夠用window.JSON.parse()
來剖析
詳細來看一個例子:點擊按鈕發送一個 POST 要求
<button id="myButton">點我</button>
myButton.addEventListener('click',function(){
let request = new XMLHttpRequest()
request.onreadystatechange = function(){ //只管往上放,不會錯過任何一個狀況,放在下面的話會錯過之前的狀況
console.log(request.readyState)
if(request.readyState === 4){ //要求完成
if(request.status === 200){ //要求勝利
let string = request.responseText
//把相符 JSON 語法的String 轉換成 JS 對應的 Object
let object = window.JSON.parse(string) //JSON.parse 是瀏覽器供應的,json3.js是有名的就是寫JSON.parse的
}else if(request.status === 400){ //要求失利
console.log("錯誤信息:" + request.status)
}
}
}
request.open('POST','http://jack.com:8889/xxx') //設置 request
request.send()
})
服務器上面就要如許寫
if(path === '/xxx' && method === 'POST'){
response.setHeader('Content-Type','text/json;charset=utf-8')
response.write(` //JSON語法
{ //Http第四部永遠是 String,這裡是相符 JSON 語法的
String,不是 Object
"note":{
"to":"張三",
"from":"李四",
"heading":"打招呼",
"content":"hi"
}
}
`)
}
JavaScript 和 JSON 語法的不同之處
JS | JSON |
---|---|
undefined | 沒有 |
null | null |
[‘a’,’b’] | [“a”,”b”] |
function{} | 沒有 |
{name:’frank’} | {“name”:”frank”} |
‘frank’ | “frank” |
var a = {};a.self = a | 搞不定(沒有變量) |
{__proto__} | 沒有原型鏈 |
跨域資本同享
Ajax 通訊只能接見同一個域下的資本,簡樸的說假如不是同一個網站,不能送 AJAX 要求,它是狀況碼status
為0。
只要協定+端口+域名如出一轍才許可發 AJAX 要求
由於 AJAX 能夠讀取相應內容,因而瀏覽器不許可你如許做
偶然也須要合理的跨域要求,有兩種要領:
- SRJ計劃
- CORS計劃
SRJ 計劃之前已講過了,這裏不在反覆,能夠看:JSONP手藝棧
這裏解說一個 CORS(Cross-Origin Resource Sharing,跨域源資本同享),基本思想就是運用自定義的 HTTP 相應頭:
在服務器上,同享的資本加上相應頭
response.setHeader('Access-Control-Allow-Origin','http://jack.com:8889')
就能夠了。
假如沒有這個頭部,或許有這個信息但源信息不婚配,要求照樣勝利,但服務器給的相應沒有相應體(第四部份)。注重:要乞降相應都不包括 Cookie 信息。