「一」请说出至少 10 个 HTTP 状态码
HTTP状态码是服务端返回给客户端的3位数字代码。
这些状态码相当于浏览器和服务器之间的对话信息。它们相互沟通两者之间的事情是正常运行了还是运行失败了或者发生了一些其他的事情(如Continue)。
了解状态码有助于快速的诊断错误,减少网站的停机时间等。
状态码共分为五类:
1xxs - 信息性:服务器正在处理请求。
2xxs - 成功信息:请求已经完成,服务器向浏览器提供了预期的响应。
3xxs –重定向:你的请求被重定向到了其他地方。服务器收到了请求,但是有某种重定向。需要进行附加操作一完成请求。
4xxs – 客户端错误:客户端发生错误,导致服务器无法处理请求。
5xxs – 服务端错误:客户端发出了有效的请求,但是服务器未能正确处理请求。
1xxs状态码
- 100 Continue:表明目前为止,所有的请求内容都是可行的,客户端应该继续请求,如果完成则忽略它。
- 101 Switching Protocol:该状态码是响应客户端Upgrade标头发送的,并且指示服务器也正在切换协议。
- 103 Early Hints:主要用于与Link链接头一起使用,以允许用户代理在服务器仍在准备响应时开始预加载资源。 在web开发的工作中,我们都会使用封装好的库进行接口请求,而且浏览器的控制台网络中也不会出现这类状态码的提示,所以这一大类基本不会接触到,了解一下即可。
2xxs状态码
- 200 OK:请求成功。成功的含义取决于HTTP方法:
- GET:请求指定的页面信息,并返回实体主体。
- HEAD:类似于 GET 请求,只不过返回的响应中没有具体的内容,用于获取报头
- POST:向指定资源提交数据进行处理请求(例如提交表单或者上传文件)。数据被包含在请求体中。POST 请求可能会导致新的资源的建立和/或已有资源的修改。
- 201 Created:请求已经成功,并因此创建了一个新的资源。这通常是在 PUT 或 POST 请求之后发送的响应。
- 202 Accepted:请求已经接收到,但是没有响应,没有结果。意味着不会有一个异步的响应去表明当前请求的结果,预期另外的进程和服务去处理请求,或者批处理。
- 204 No Content:服务器成功处理了请求,但不需要返回任何实体内容,并且希望返回更新了的元信息。遇到复杂请求时候,浏览器会发送一个 OPTION 方法进行预处理返回响应。
- 205 Reset Content:服务器已经成功处理了请求,但是没有返回任何内容。与204响应不同,返回此状态码的响应要求请求者重置文档视图。
- 206 Partial Content:该状态码表示客户端进行了范围请求,而服务器端执行了这部分的 GET 请求。响应报文中包含由 Content-Range 指定范围的实体内容。
使用的最多的2xxs状态码是
200
和204
,在遇到204状态码的时候,要注意一下自己发的请求是不是复杂请求。如果是复杂请求,那么在得到204返回时,浏览器有没有接受了这个请求的返回,如果没有,要叫后端搞下相关配置。
3xxs状态码
- 301 Moved Permanently:被请求的资源已永久移动到新位置,并且将来任何对此资源的引用都应该使用响应返回的若干个 URI 之一。
- 302 Found(Previously "Moved temporarily"):请求的资源现在临时从不同的 URI 响应请求。由于这样的重定向是临时的,客户端应当继续向原有地址发送以后的请求。只有在 Cache-Control 或 Expire s中进行了指定的情况下,这个响应才是可缓存的。
- 303 See Other:对当前的请求的响应可以在另一个 URI 上被找到,而且客户端应该采用 GET 的方式访问那个链接。这个方法的存在主要是为了允许由脚本激活的 POST 请求输出重定向到一个新的资源。
- 304 Not Modified:如果客户端发送了一个带条件的 GET 请求且该请求已被允许,而文档的内容(自上次访问以来或者根据请求的条件)并没有改变,则服务器应当返回这个状态码。304 响应禁止包含消息体,因此始终以消息头后的第一个空行结尾。请求的时候一般结合If-Modified-Since头部使用。
- 307 Temporary Redirect:307的意义如上302。与历史上302不同的是在重新发出原始请求时不允许更改请求方法。比如,使用 POST 请求始终就该用 POST 请求。 注意⚠️: 304,它并不是表示重定向的信息提示,而是表示资源未被更改。
4xxs状态码
- 401 Unauthorized:这意味着你的登录凭证无效。服务器不知道你是谁,你需要尝试重新登录。
- 403 Forbidden:服务器已经理解请求,但是拒绝执行它。与401不同,403知道是你登录了,但是还是拒绝了你。
- 404 Not Found:请求失败,你请求所希望得到的资源未在服务器上发现。
- 410 Gone:被请求的资源在服务器上已经不再可用,而且没有任何已知的转发地址。
- 422 Unprocessable Entity:请求格式良好,但是由于语义错误而无妨遵循。这时候要检查下自己的传参格式语义是否正确。
- 429 Too Many Requests:用户在给定的时间内发送了太多请求(“限制请求速率”)。在 DDOS 攻击中就可以使用到了。
5xxs状态码
- 500 Internal Server Error:服务器内部错误,服务器遇到了不知道如何处理的情况。比如后端同学写错了model。
- 501 Not Implemented:表示request header 里的 method 或 Content-* 时不被服务器支持,无法被处理。另服务器必须支持的方法(即不会返回这个状态码的方法)只有 GET 和 HEAD。501 响应默认是可缓存的。
- 503 Service Unavailable:服务器没有准备好处理请求。常见的原因是服务器因维护或重载而停机。
- 504 Gateway Timeout:网关超时,服务器未能快速的做出反应。请求接口返回 pedding 时间过长基本就是这个问题了。
「二」DOM 事件相关
什么是事件委托?
由于冒泡阶段,浏览器从用户点击的内容从下往上遍历至 window,逐个触发事件处理函数,因此可以监听一个祖先节点(例如爸爸节点、爷爷节点)来同时处理多个子节点的事件。
简单理解:委托一个元素帮我监听我本该监听的事件。
事件委托应用场景:查看链接
事件委托的优点:
- 省监听数量(省内存)
- 可以监听动态元素
怎么阻止默认动作?
阻止默认动作的语法是event.preventDefault()
怎么阻止事件冒泡?
捕获不可以取消,但是冒泡可以取消,event.stopPropagation()
可中断冒泡,浏览器不再向上走。
但是有一些事件不可取消冒泡,比如scroll事件。那么如何防止滚动?
- 可阻止
wheel
和touchstart
的默认动作; - 再让css取消滚动条
「三」对 Promise 的了解
Promise 的用途
- Promise 是前端解决异步问题的统一方案。比传统的解决方案回调函数和事件更合理和更强大。
- 有了Promise对象,就可以将异步操作以同步操作的流程表达出来,避免了层层嵌套的回调函数。
- 一个 Promise 必须提供一个 then 方法以访问其当前值、终值和据因。
- Promise的每个操作返回的都是Promise对象,可支持链式调用。
- 通过 then 方法执行回调函数,Promise的回调函数是放在事件循环中的微队列。
如何创建一个 new Promise 及使用 Promise.prototype.then
function fn(){
return new Promise((resolve, reject)=>{
resolve('成功!') //成功时调用 resolve(数据)
// 或者 reject(new Error("出错了!")); //失败时调用 reject(错误)
})
}
fn().then(value => {
console.log(value); // 成功!
}, reason => {
console.error(reason); // 出错了!
})
// fn().then(success1, fail1).then(success2, fail2)
promise.then(onFulfilled, onRejected)
回调函数只能执行一次,且返回 promise 对象
如何使用 Promise.all
Promise.all() 方法用于将多个 Promise 实例,包装成一个新的 Promise 实例。
Promise.all([promise1, promise2]).then(success1, fail1)
promise1 和 promise2 都成功才会调用 success1
如何使用 Promise.race
Promise.race() 方法同样是将多个 Promise 实例,包装成一个新的 Promise 实例。
Promise.race([promise1, promise2]).then(success1, fail1)
promise1 和 promise2 只要有一个成功就会调用 success1
「四」说说跨域
什么是同源
-
源=协议+域名+端口号。 如果两个url的协议、域名、端口号完全一致,那么这两个url就是同源的。
我们可以通过window.origin或location.origin得到当前源。 -
同源策略:不同源之间的页面,不准互相访问数据。 浏览器规定:如果JS运行在源A里,那么就只能获取源A的数据,不能获取源B的数据,即不允许跨域。
注意⚠️:同源策略限制的是数据访问,我们引用CSS、JS脚本和图片等的时候,其实并不知道其内容,只是在引用。引用某个东西和拿到它本身的数据是两件不同的事情。
假设 frank.com:8888/index.html引用了qq.com:9999/1.js,那么就说1.js运行在源frank.com:8888里,注意,这和qq.com:9999没有关系,虽然1.js是从它那里下载的。所以1.js就只能获取frank.com:8888的数据,这就是浏览器的功能,浏览器就是故意这样设计的。
- 浏览器这样做的目的是保护用户隐私
正常页面的JS和黑客的JS发的请求几乎一模一样,除了referer有区别。
Referer是HTTP请求头的一个字段,包含了当前请求页面的来源页面的地址,通过该字段,我们可以检测访客是从哪里来的。
虽然后台可以查看referer可以甄别是谁在发请求,但是如果这个网站的后端开发工程师忘记检查了呢?安全链条的强度取决于最弱的一环,为了避免用户数据被恶意盗窃,浏览器规定了同源策略。
什么是跨域
跨域,即浏览器试图执行其他网站的脚本。但是由于同源策略的限制,导致我们无法实现跨域。
CORS 跨域
CORS的全称是"跨域资源共享"(Cross-origin resource sharing)
在同源策略的规定下,AJAX只能同源使用。但是CORS允许浏览器向跨源服务器,发出XMLHttpRequest请求。
具体操作只需一行代码,在服务器端设置Access-Control-Allow-Origin即可,这相当于让服务器允许该客户端请求。
语法:response.setHeader('Access-Control-Allow-Origin', '源')
- 如何理解CORS?
如果frank.com和qq.com这两个网站都是我的,我就是想让frank.com去访问qq.com里面的数据应该怎么办呢?
只需要qq.com在响应头
里写frank.com可以访问即可。这就是CORS。
实现CORS通信的关键是服务器。只要服务器实现了CORS接口,就可以跨源通信。
JSONP 跨域
JSONP 就是我们在跨域的时候由于当前的浏览器不支持 CORS 或者因为某些条件不支持 CORS,我们必须使用另外一种方式来跨域。
于是我们就请求一个 js 文件,之前提到过,虽然浏览器有同源策略,但是script标签引用JS是不受限制的。这个 js 文件会执行一个回调,回调里面就有我们需要的数据。
(回调的名字是可以随机生成的随机数,然后把名字以callback的参数传给后台,后台会把这个函数再次返回给我们并执行。)
// 封装JSONP
function jsonp(url){
return new Promise((resolve, reject)=>{
const random = 'frankJSONPCallbackName'+Math.random()
window[random] = (data) => {
resolve(data)
}
const script = document.createElement('script')
script.src = `${url}?callback=${random}`
// 让页面不存在多的script标签
script.onload = ()=>{
script.remove()
}
script.onerror = ()=>{
reject()
}
document.body.appendChild(script)
})
}
// 请求jsonp
jsonp('http://qq.com:8888/friends.js')
.then((data)=>{
console.log(data)
})
- 优点: ①可以跨域; ②兼容IE
- 缺点: ①由于它是script标签,所以它读不到AJAX那么精确的状态,不知道状态码是什么,也不知道header; ② 由于它是script标签,只能发 GET 请求,不支持 POST