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) {
// ....
}
}
};
responseresponse 返回响应文本。返回的类型为 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: 请求的 URLasync: 是否异步执行操作,默认为 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实例
aborterrorloadloadstartloadendprogresstimeoutfetch除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实例来中断。