enctype
, 提交数据的格式,用 enctype
将数据发送到服务端时指定的编码类型。
application/x-www-form-urlencoded
:
在node
中的http.createServer
方法中,通过监听req
的data
数据,可以接受到相关传参数据。
对于application/x-www-form-urlencoded
传参方式,可以直接获取到传参xx=xxx&xx=xxx
req.on('data', (chunk) => {
buffer += chunk.toString('utf8');
});
multipart/form-data
而对于multipart/form-data
,则获取的数据不同,会读取到content-type
后边的boundary
数据
比如 'content-type': 'multipart/form-data; boundary=----WebKitFormBoundaryxxxxxxxxxxxx',
,
此时读取的到的为------WebKitFormBoundaryxxxxxxxxxxxx
,可以使用类似multiparty
进行解析。
const form = new multiparty.Form();
form.parse(req, function (err, fields, files) {
// fields 是通过formData传入的字段跟值
// files 则是文件
});
text/plain
纯文本格式
表单开始提交,浏览器就会刷新页面,然后在新页面里告诉你操作是成功了还是失败了。如果不幸由于网络太慢或者其他原因,就会得到一个 404
页面。
AJAX
是一种在无需重新加载整个网页的情况下,能够更新部分网页的技术。
在现代浏览器上写 AJAX
主要依靠 XMLHttpRequest
对象
AJAX
请求是异步执行的,也就是说,要通过回调函数获得响应
var request = new XMLHttpRequest(); // 新建XMLHttpRequest对象
request.onreadystatechange = function () {
// 状态发生变化时,函数被回调
if (request.readyState === 4) {
// 成功完成
// 判断响应结果:
if (request.status === 200) {
// 成功,通过responseText拿到响应的文本:
console.log(request.responseText);
} else {
// 失败,根据响应码判断失败原因:
console.log(request.status);
}
} else {
// HTTP请求还在继续...
}
};
// 发送请求:
request.open('GET', '/api/xxxx');
request.send();
XMLHttpRequest
(XHR
)对象用于与服务器交互。通过 XMLHttpRequest
可以在不刷新页面的情况下请求特定 URL
,获取数据。这允许网页在不影响用户操作的情况下,更新页面的局部内容。
XMLHttpRequest.readyState
属性返回一个 XMLHttpRequest
代理当前所处的状态。
UNSENT
)XMLHttpRequest
代理已被创建,但尚未调用 open()
方法。OPENED
)open()
方法已经被触发。在这个状态中,可以通过 setRequestHeader()
方法来设置请求的头部,可以调用 send()
方法来发起请求。HEADERS_RECEIVED
)send()
方法已经被调用,响应头也已经被接收。LOADING
)responseType
属性是“text
”或空字符串,responseText
将会在载入的过程中拥有部分响应数据。DONE
)var xhr = new XMLHttpRequest();
console.log('UNSENT', xhr.readyState); // readyState 为 0
xhr.open('GET', '/api', true);
console.log('OPENED', xhr.readyState); // readyState 为 1
xhr.onprogress = function () {
console.log('LOADING', xhr.readyState); // readyState 为 3
};
xhr.onload = function () {
console.log('DONE', xhr.readyState); // readyState 为 4
};
xhr.send(null);
progress
事件监听如果是同步请求(open
方法的第三个参数为false
)则不会触发。
onreadystatechange
当readyState
属性变化时,会触发这个方法。
// 在onreadystatechange方法中判断readyState的状态码
request.onreadystatechange = function () {
if (request.readyState === 4) {
if (request.status === 200) {
// ....
}
}
};
response
response
返回响应文本。返回的类型为 ArrayBuffer
、Blob
、Document
、JavaScript Object
或字符串中的一个。这取决于请求的 responseType
属性。
responseType
用于指定响应中包含的数据类型。如果responseType
的值为一个空字符串,那么text
为默认值,response
就是一个字符串。
responseText
返回的纯文本的值。
只有当readyState
的值为 4 及status
为 200 时,responseText
才是完成的返回数据。
responseURL
返回当前请求的url
,如果是经过多次重定向的那么值为最终的url
.
XMLHttpRequest
和fetch
内部对重定向做了处理,不会重新建立连接
responseXML
当响应头中的content-type
为text/xml
或者直接设置responseType
为document
,响应响应则会按照text/xml
进行解析。
status
响应状态码,遵循标准响应码规范。
HTTP
响应状态码用来表明特定 HTTP
请求是否成功完成。 响应被归为以下五大类:
规范
statusText
响应状态码对应的文本信息。如果服务器未明确指定一个状态文本信息,则statusText
的值将会被自动赋值为"OK"
。
timeout
无符号长整型数,代表着一个请求在被自动终止前所消耗的毫秒数。默认值为 0
,意味着没有超时。超时并不应该用在同步 XMLHttpRequests
请求中,否则将会抛出一个 InvalidAccessError
类型的错误。当超时发生, timeout
事件将会被触发。
var xhr = new XMLHttpRequest();
xhr.open('GET', '/server', true);
xhr.timeout = 2000; // 超时时间,单位是毫秒
xhr.onload = function () {
// 请求完成。在此进行处理。
};
xhr.ontimeout = function (e) {
// XMLHttpRequest 超时。在此做某事。
};
xhr.send(null);
upload
用来表示上传的进度
withCredentials
是否会携带用户凭证(cookie
)。
默认false
,即不携带,在http
的request
中不传cookie
字段。
如果在设置为true
,那么服务端的响应头也需要设置Access-Control-Allow-Credentials
成true
,否则也不能正常访问(CORS
错误)。
通过设置withCredentials
为true
可以获取第三方的cookies
,如果以cookie
作为凭证,容易造成CORS
攻击。
可能攻击的方式:
- 如果以
cookie
为凭证且指定Access-Control-Allow-Origin
为*
,那么使用iframe
嵌套直接伪造请求就可以实现cors
攻击。- 如果以
cookie
为凭证但是指定Access-Control-Allow-Origin
为对应的域名,可以在控制台中直接发送请求进行攻击。
abort
如果请求已被发出,则立刻中止请求。
当一个请求被终止,它的 readyState
将被置为 XMLHttpRequest.UNSENT (0)
,并且请求的 status
置为 0
。
即使请求中断了,但是服务端仍然接受到请求,只不过浏览器拒收
一个请求如果还没响应,这时候再发请求那么xmlHttpRequest
内部会自动将前一个请求进行中断之后发送最新的请求。
open
初始化一个新创建的请求,或重新初始化一个请求。
xhrReq.open(method, url, async, user, password);
method
: 使用的 HTTP
方法,比如 GET
、POST
、PUT
、DELETE
、等。对于非 HTTP(S) URL
被忽略。url
: 请求的 URL
async
: 是否异步执行操作,默认为 true
。如果值为 false
,send()
方法直到收到答复前不会返回。如果 true
,已完成事务的通知可供事件监听器使用。如果 multipart
属性为 true
则这个必须为 true
,否则将引发异常。user
: 可选的用户名用于认证用途;默认为 null
。password
: 可选的密码用于认证用途,默认为 null
。send
发送请求,如果请求类型为异步请求,send()方法的返回值会立即返回.
getAllResponseHeaders
返回响应的header
信息(String
类型),以CRLF
分割.如果没有接收到响应头,则返回null
。
通过以下方式可以进行解析对象:
const parsedHeaders = {};
request
.getAllResponseHeaders()
.split('\n')
.forEach((item) => {
const i = item.indexOf(':');
const key = item.substr(0, i).replace(/^\s*/, '').replace(/\s*$/, '');
const val = item.substr(i + 1);
if (key) {
if (key === 'set-cookie') {
parsedHeaders[key] = (parsedHeaders[key] ? parsedHeaders[key] : []).concat([val]);
} else {
parsedHeaders[key] = parsedHeaders[key] ? parsedHeaders[key] + ', ' + val : val;
}
}
});
getResponseHeader
获取某个header
属性的值,name
参数为需要获取属性值的key
.如果header
对象不存在此属性或者获取header
对象失败,则返回null
.
setRequestHeader
设置HTTP
请求头.此方法需要在open()
之后和send()
之前执行.如果设置了不被支持的属性,请求可能会报错。
XMLHttpRequest.setRequestHeader(key, value);
对于FormData
、Blob
、file
这个数据,不需要手动设置Content-Type
,浏览器会自动进行设置。
可通过addEventListener
或者on + 事件名
进行监听XMLHttpRequest
实例
abort
error
load
loadstart
loadend
progress
timeout
fetch
除XMLHttpRequest
外,浏览器还提供了一个更简单的方法fetch
。
fetch
接受两个参数:
input
: 可以是请求URL
,也可以是一个Request
对象(实验中)。
init
: 一个配置项对象
method
: 请求方法headers
: 请求头.
如果是post
请求,需要传content-type
进行标识
formData
格式数据不需要传content-type
,浏览器会进行处理。
Blob
数据如果不传content-type
,会报错。
String
、Object
格式数据默认content-type
是text/plain;charset=UTF-8
,Object
数据在传递时会被转换成String
格式(调用toString
方法变成[object Object]
, 需要使用JSON.stringify
方法转换成string
)。
body
: 请求的 body
信息。注意 GET
或 HEAD
方法的请求不能包含 body
信息, 不然会报错mode
: 请求方式(在浏览器头中的sec-fetch-mode
字段), 如cors
、no-cors
或者 same-origin
。
默认cors
no-cors
,如果是跨域,不会报错,浏览器中的请求其实已经成功,但是fetch
会对response
进行拦截,返回的promise
是请求失败的。请求方法只限于 GET
、POST
和 HEAD
,并且只能使用有限的几个简单标头,不能添加跨域的复杂标头,相当于提交表单所能发出的请求。
same-origin
,跨域会报错。
credentials
: 请求的 credentials
,如 omit
、same-origin
或者 include
。
same-origin
:默认值,同源请求时发送 Cookie
,跨域请求时不发送。
include
:不管同源请求,还是跨域请求,一律发送 Cookie
。
omit
:一律不发送。
cache
: 请求的 cache
模式:default
、 no-store
、 reload
、 no-cache
、 force-cache
或者 only-if-cached
。
default
:默认值,先在缓存里面寻找匹配的请求。
no-store
:直接请求远程服务器,并且不更新缓存。
reload
:直接请求远程服务器,并且更新缓存。
no-cache
:将服务器资源跟本地缓存进行比较,有新的版本才使用服务器资源,否则使用缓存。
force-cache
:缓存优先,只有不存在缓存的情况下,才请求远程服务器。
only-if-cached
:只检查缓存,如果缓存里面不存在,将返回 504 错误。
redirect
: 可用的 redirect
模式:follow
(自动重定向), error
(如果产生重定向将自动终止并且抛出一个错误),或者 manual
(手动处理重定向)。在 Chrome
中默认使用 follow
(Chrome 47
之前的默认值是 manual
)。
follow
默认值,fetch()
跟随 HTTP
跳转
error
,当请求返回是重定向时,会报错
manual
, fetch()
不跟随 HTTP
跳转,response.url
属性会指向当前 URL
referrer
: 一个 USVString
可以是 no-referrer
、client
或一个 URL
。默认是 client
。xxx
),那么请求中的refer
字段值为host + xxx
。referer
标头)。referrerPolicy
: 指定了 HTTP
头部 referer
字段的值。可能为以下值之一:no-referrer
、 no-referrer-when-downgrade
、origin
、origin-when-cross-origin
、 unsafe-url
。
no-referrer
不携带referer
字段
no-referrer-when-downgrade
:默认值,总是发送Referer
标头,除非从 HTTPS
页面请求 HTTP
资源时不发送
origin
,referer
标头只包含域名,不包括路径
origin-when-cross-origin
:同源请求Referer
标头包含完整的路径,跨域请求只包含域名。
unsafe-url
:不管什么情况,总是发送Referer
标头。
strict-origin
:Referer
标头只包含域名,HTTPS
页面请求 HTTP
资源时不发送Referer
标头。
strict-origin-when-cross-origin
:同源请求时Referer
标头包含完整路径,跨域请求时只包含域名,HTTPS
页面请求 HTTP
资源时不发送该标头。
integrity
: 包括请求的 subresource integrity
值(例如: sha256-BpfBw7ivV8q2jLiT13fxDYAe2tJllusRSZ273h2nFSE=
)。
integrity
:指定一个哈希值,用于检查 HTTP
回应传回的数据是否等于这个预先设定的哈希值。
比如,下载文件时,检查文件的 SHA-256
哈希值是否相符,确保没有被篡改
fetch('http://site.com/file', {
integrity: 'sha256-abcdef',
});
signal
:指定一个 AbortSignal
实例,用于取消fetch()
请求返回一个promise
,resolve
时回传 Response
对象。
取消请求
let controller = new AbortController();
fetch(url, {
signal: controller.signal,
});
controller.signal.addEventListener('abort', () => console.log('abort!'));
// controller.abort()方法用于发出取消信号。这时会触发abort事件,这个事件可以监听
controller.abort(); // 取消
// 可以通过controller.signal.aborted属性判断取消信号是否已经发出
console.log(controller.signal.aborted); //
当调用了abort
方法后,controller
实例就不能再使用了,controller.signal.aborted
已经变成true
了,该属性只读,不能修改值来实现再次使用(会报错),只能通过在创建一个AbortController
实例来中断。