浏览器中的XMLHttpRequest和Fetch
XMLHttpRequest
是什么
使用
XMLHttpRequest
在脚本中请求特定的url,获取数据。
readyState
请求的状态码
| 值 | 状态 | 描述 |
|---|---|---|
| 0 | UNSENT | XMLHttpRequest被创建,且open() 方法未调用 |
| 1 | OPENED | open() 已经被调用 |
| 2 | HEADERS_RECEIVED | send() 已经被调用,且响应头部和状态已经获得 |
| 3 | LOADING | 下载中,response已经包含部分数据 |
| 4 | DONE | 请求完成 |
onreadystatechange
当
readyState
属性发生变化时,会调用
onreadystatechange
函数
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function () {
// 0 1 ""
// 200 2 ""
// 200 3 "第一次输出"
// 200 3 "第一次输出延迟2秒后的输出"
// 200 3 "第一次输出延迟2秒后的输出延迟4秒后的输出"
// 200 4 "第一次输出延迟2秒后的输出延迟4秒后的输出"
console.log(this.status, this.readyState, this.response);
xhr.open('GET', url);
xhr.send();
status
返回的状态码
statusText
返回的响应状态
response
响应内容,数据类型通过
responseType
定义
responseType
| 值 | 描述 |
|---|---|
| 为空时,默认和text相同 | |
| arraybuffer | response是一个 ArrayBuffer 对象 |
| blob | response是一个 Blob 对象 |
| document | response是一个HTML Document 或者 XML Document |
| json | response是一个js对象 |
| text | response是一个DOMString`对象 |
timeout
设置请求超时时间,当超时发生后,请求的
readyState
会变为4(DONE),
status
由已接受到的200变为0,
respose
置为空。触发timeout事件。
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function () {
// 0 1 ""
// 200 2 ""
// 200 3 "第一次输出"
// 0 4 ""
console.log(this.status, this.readyState, this.response);
xhr.addEventListener('timeout', function () {
// timeout 0 4
console.log('timeout', this.status, this.readyState, this.response);
xhr.addEventListener('error', function () {
console.log('error', this.status, this.readyState, this.response);
xhr.open('GET', url);
xhr.timeout = 1000;
xhr.send();
withCredentials
默认值是
false
,在跨域请求时,不携带
cookie
,且响应的
Set-Cookie
不生效。设置为
true
时,跨域请求会带上
cookie
,且响应的
Set-Cookie
会生效。对同源请求,该属性不生效。
// 验证withCredentials可以发送cookies、设置cookies
var xhr = new XMLHttpRequest();
var url = 'http://localhost:8090/setcookie?c=' + encodeURIComponent('random=' + Math.random());
xhr.onreadystatechange = function () {
console.log(this.status, this.readyState, this.response);
xhr.open('GET', url);
xhr.withCredentials = true;
xhr.send();
// 请求完成后,在开发者面板可以看到,域名localhost:8090下的cookies中存在由响应设置的random值
响应中的
Set-Cookie
:
请求头中带有
cookie
:
域名下的
cookie
被成功设置
注意 :
-
withCredentials依然要遵循浏览器的安全策略,不同域名下的cookie是隔离的,不能相互访问对方域名下的cookie
2. 响应头需要设置
Access-Control-Allow-Origin
和
Access-Control-Allow-Credentials
,否则跨域请求会失败
self.set_header('Access-Control-Allow-Origin', 'http://localhost:8210')
self.set_header('Access-Control-Allow-Credentials', 'true')
setRequestHeader
设置HTTP请求头,需要在
open()
函数调用和
send()
函数调用之间调用。 考虑到安全问题,浏览器会禁止用户设置某些请求头。被禁止的请求头包括
-
以
Proxy-开头 -
以
Sec-开头 -
Accept-Charset -
Accept-Encoding -
Access-Control-Request-Headers -
Access-Control-Request-Method -
Connection -
Content-Length -
Cookie -
Cookie2 -
Date -
DNT -
Expect -
Feature-Policy -
Host -
Keep-Alive -
Origin -
Proxy- -
Sec- -
Referer -
TE -
Trailer -
Transfer-Encoding -
Upgrade -
Via
getResponseHeader
获取HTTP响应头
Fetch
Fetch是一个全局函数,用来从网络上获取资源,具有两个参数
resource
,
init
。返回结果是Promise,请求结束时,返回
Response
对象。
resource
资源的路径 或者
Request
对象
init
method
请求方法
headers
请求头,考虑到安全问题,浏览器会禁止用户设置某些请求头
body
请求体,可以是
Blob
,
BufferSource
,
FormData
,
URLSearchParams
,
USVString
,
ReadableStream
。需要注意,
GET
和
HEAD
请求不能设置
body
mode
可能的值是
cors
,
no-cors
,
same-origin
,具体用途不明
credentials
一个枚举值,可选的值有
omit
、
same-origin
或者
include
。默认是
same-origin
,当发起请求时,只有同源的情况下,会带上
cookie
,跨域时不带
cookie
。设置
omit
时,任何情况下都不带
cookie
。设置
include
的情况下,同源情况下带上
cookie
,跨域时也带
cookie
// fetch跨域
var url = 'http://localhost:8090/setcookie?c=' + encodeURIComponent('random=' + Math.random());