歷史上發(fā)送請(qǐng)求的方式
- 用 form 可以發(fā)請(qǐng)求羡疗,但是會(huì)刷新頁面或新開頁面
- 用 a 可以發(fā) get 請(qǐng)求染服,但是也會(huì)刷新頁面或新開頁面
- 用 img 可以發(fā) get 請(qǐng)求,但是只能以圖片的形式展示
- 用 link 可以發(fā) get 請(qǐng)求叨恨,但是只能以 CSS柳刮、favicon 的形式展示
- 用 script 可以發(fā) get 請(qǐng)求,但是只能以腳本的形式運(yùn)行
注意:以上除了form特碳,都只能發(fā)get請(qǐng)求
有沒有什么方式可以實(shí)現(xiàn):
1.get诚亚、post、put午乓、delete 請(qǐng)求都行
2.想以什么形式展示就以什么形式展示
XMLHttpRequest的發(fā)明
微軟當(dāng)時(shí)取得了重大突破:
IE 5 率先在 JS 中引入 ActiveX 對(duì)象(API)站宗,使得 JS 可以直接發(fā)起 HTTP 請(qǐng)求。
隨后 Mozilla益愈、 Safari梢灭、 Opera 也跟進(jìn)了,取名 XMLHttpRequest蒸其,并被納入 W3C 規(guī)范
AJAX
Jesse James Garrett 將下面的技術(shù)取名叫做 AJAX:異步的 JavaScript 和 XML (async JavaScript and XML)
1.使用XMLHttpRequest發(fā)請(qǐng)求
2.服務(wù)器返回XML格式的字符串
3.JS解析XML敏释,并局部更新頁面
let request = new XMLHttpRequest()
// 盡量放在最上面,這樣就不會(huì)錯(cuò)過任何變化
// 如果放在request.send()之后摸袁,這時(shí)候readyState已經(jīng)從0變?yōu)?钥顽,就只能捕獲到2,3靠汁,4蜂大。
request.onreadystatechange = () => {
if (request.readyState === 4) {
if (request.status >= 200 && request.status < 300) {
console.log('請(qǐng)求成功')
} else if (request.status >= 400) {
console.log('請(qǐng)求失敗')
}
}
}
//初始化請(qǐng)求
request.open('GET', '/xxx')
//發(fā)送請(qǐng)求
request.send()
readyState:請(qǐng)求的五種狀態(tài)
0: 未打開 open()方法還未被調(diào)用
1: 未發(fā)送 send()方法還未被調(diào)用
2: 已經(jīng)獲取響應(yīng)頭 send()方法已經(jīng)被調(diào)用,響應(yīng)頭和響應(yīng)狀態(tài)已經(jīng)返回
3: 正在下載響應(yīng)體 響應(yīng)體下載中蝶怔;responseText中已經(jīng)獲取了部分?jǐn)?shù)據(jù)
4: 請(qǐng)求完成 整個(gè)請(qǐng)求過程完成
JSON
JSON 是一門抄襲/借鑒 JavaScript 的語言奶浦,同時(shí)也是一種數(shù)據(jù)交互格式,JSON 是 JavaScript 的子集(或者說 JSON 只抄襲了一部分 JavaScript 語法踢星,而且沒有新增任何原創(chuàng)的語法)
區(qū)別:SON 不支持函數(shù)澳叉、undefined、變量沐悦、引用成洗、單引號(hào)字符串、對(duì)象的key不支持單引號(hào)也不支持不加引號(hào)藏否、沒有內(nèi)置的 Date泌枪、Math、RegExp 等秕岛。而 JavaScript 全都支持碌燕。
JavaScript | JSON |
---|---|
undefined | 無 |
null | null |
[ 'a', 'b' ] | [ "a", "b" ] |
'keller' | "keller" |
{ name: 'keller' } | { "name": "keller" } |
function fn() {} | 無 |
var a = {}; a.self = a | 無 |
__proto__ | 無 |
那么現(xiàn)在再結(jié)合前后端一起看一下代碼
前端代碼
myButton.addEventListener('click', (e) => {
let request = new XMLHttpRequest()
request.open('get', '/xxx') // 配置request
request.send()
request.onreadystatechange = () => {
if (request.readyState === 4) {
console.log('請(qǐng)求響應(yīng)都完畢了')
console.log(request.status)
if (request.status >= 200 && request.status < 300) {
console.log('說明請(qǐng)求成功')
console.log(typeof request.responseText)
console.log(request.responseText)
let string = request.responseText
// 把符合 JSON 語法的字符串
// 轉(zhuǎn)換成 JS 對(duì)應(yīng)的值
let object = window.JSON.parse(string)
// JSON.parse 是瀏覽器提供的
console.log(typeof object)
console.log(object)
console.log('object.note')
console.log(object.note)
} else if (request.status >= 400) {
console.log('說明請(qǐng)求失敗')
}
}
}
})
后端代碼:
if (path === '/xxx') {
response.statusCode = 200
response.setHeader('Content-Type', 'text/json;charset=utf-8')
response.setHeader('Access-Control-Allow-Origin', 'http://frank.com:8001')
response.write(`
{
"note":{
"to": "frank",
"from": "keller",
"heading": "打招呼",
"content": "hello"
}
}
`)
response.end()
}
同源策略和CORS跨域
同源策略的本質(zhì)是:一個(gè)域名的JS误证,在未經(jīng)允許的情況下,不能讀取另一個(gè)域名的內(nèi)容修壕。
只有 協(xié)議+域名+端口 一模一樣才允許發(fā) AJAX 請(qǐng)求
1.http://baidu.com 可以向 http://www.baidu.com發(fā) AJAX 請(qǐng)求嗎愈捅?(不可以)
2.http://baidu.com:80可以向http://baidu.com:81發(fā) AJAX 請(qǐng)求嗎?(不可以)
突破同源策略 === 跨域慈鸠,通過使用JSONP以及CORS可以實(shí)現(xiàn)蓝谨,這里著重介紹CORS
CORS(跨站資源共享): Cross-Origin-Resource-Sharing
通俗理解:CORS 可以告訴瀏覽器,我倆一家的青团,別阻止他
實(shí)現(xiàn)方式:讓目標(biāo)站點(diǎn)的后端程序員在相應(yīng)API的響應(yīng)頭里添加以下代碼(切記不要在全網(wǎng)站加譬巫,需要哪個(gè)API,就在哪個(gè)API里加)
后端代碼如下:
//允許http://keller.com:8001向我發(fā)起請(qǐng)求
response.setHeader('Access-Control-Allow-Origin', 'http://keller.com:8001')
//允許所有域名向我發(fā)起請(qǐng)求
response.setHeader('Access-Control-Allow-Origin', '*')