常见 http 状态码
状态码为三位数,分成五类,数字第一位代表分类,范围就是100 ~ 599
1xx:提示信息,表示目前是协议处理的中间状态,还需要后续的操作
2xx: 成功,报文已经收到并被正确处理
- "200 OK" 表示请求成功,服务器如客户端所期望的那样返回了处理结果
- "204 No Content" 表示请求成功,但响应体没有数据
- "206 Partial Content" 表示请求成功,但响应体只有部分数据
3xx:重定向,资源位置发生变动,需要客户端重新发送请求
- "301 Moved Permanenly" 永久重定向,请求的资源已经不存在了,需要用新的 url 再次访问
- "302 Found" 暂时重定向,请求的资源还在,但暂时要用另一个 url 访问
- "304 Not Modified" 缓存重定向,资源未修改,用于缓存控制
4xx:客户端错误,请求报文有误,服务器无法处理
- "400 Bad Request" 请求报文错误,但具体是什么错误没有明确,只是一个笼统的错误
- "403 Forbidden" 服务器禁止访问资源。服务器可在 body 里详细说明拒绝请求的原因
- "404 Not Found" 资源在本服务器上未找到
5xx:服务器错误,服务器在处理请求时内部发生了错误
- "500 Internal Server Error" 服务器在执行请求时发生了错误
- "501 Not Implemented" 客户端请求的功能还不支持
- "502 Bad Gateway" 服务器作为网关或代理时发生了错误
- "504 Servive Unavailable" 服务器当前很忙,暂时无法响应服务
AJAX 原理
let xhr = new XMLHttpRequest()
// 开启请求
xhr.open('get')
// 挂载回调,readystate 改变时触发
// xhr 有5个状态
// readystate === 0, 代理被创建,但尚未调用 open() 方法
// readystate === 1, open() 方法已经被调用
// readystate === 2, send() 方法已经被调用,并且头部和状态已经可获得
// readystate === 3, 下载中; responseText 属性已经包含部分数据
// readystate === 4, 下载操作已完成
xhr.onreadystatechange = function () {
if (xhr.readyState === 4) {
if ((xhr.status >= 200 && xhr.status < 300) || xhr.status === 304) {
cb(xhr.responseText);
}
}
};
// 发送请求
xhr.send()
promise 封装 AJAX
function Ajax(obj) {
return new Promise((res, rej) => {
const xhr = new XMLHttpRequest();
xhr.onreadystatechange = () => {
if (xhr.readyStatus === 4 && xhr.status === 200) {
res(xhr.responseText);
} else {
rej({
errorType: 'onerror',
xhr,
});
}
};
if (obj.method === 'POST') {
xhr.open('POST', obj.url, true);
xhr.responseType = 'json';
xhr.setRequestHeader('Accept', 'application/json');
const postData = JSON.parse(obj.data);
xhr.send(postData);
} else if (obj.method === 'GET') {
const newUrl = (function (url, data) {
let queryString = url.includes('?') ? '&' : '?';
for (let key in data) {
queryString += `${encodeURIComponent(key)}=${encodeURIComponent(
data[key]
)}&`;
}
return url + queryString.slice(0, -1);
})(obj.url, obj.data);
xhr.open('GET', newUrl, true);
xhr.send();
}
});
}
跨域
同源策略:浏览器只允许同源地址请求资源,域名端口协议三者都相同即为同源
常见跨域方法:
- CORS:服务器端 response header 设置Access-Control-Allow-Origin: *
- 服务端没有同源策略的限制,可以通过中间件服务器转发请求实现跨域
- JSONP
- 浏览器不限制 script 标签请求 js 脚步
- 浏览器端在 window 上挂载一个回调函数,通过 script.src 将函数名称传给服务端
- 服务器端发送 js 脚本将数据调用传入回调函数中
- script 请求成功后执行脚本调用该回调函数,得到服务端传来的数据
(function (window, document) {
'use strict';
let jsonp = function (url, data, callback) {
// 1.data => url searchParams
for (let key in data) {
let queryString = url.indexOf('?') === -1 ? '?' : '&';
queryString += `${key}=${data[key]}&`;
}
// 2.将回调函数名加入 url searchParams
let cb_fn_name = 'my_json_cb' + Math.random().toString().replace(',', '');
queryString += 'callback=' + cb_fn_name;
// 3.创建 script 标签加入到页面中
let scriptEle = document.createElement('script');
scriptEle.src = url + queryString;
// 4.挂载回调函数
window[cb_fn_name] = function (data) {
callback(data);
document.body.removeChild(scriptEle);
};
};
window.$jsonp = jsonp;
})(window, document);
优点: 兼容性好
缺点: 只支持 GET 请求(script 只能 get)。