共计 2988 个字符,预计需要花费 8 分钟才能阅读完成。
HTTP 基础
其实很多面试问 HTTP 的 3 次握手,4 次挥手,我觉得价值不大,可以帮助你理解 HTTP 的原理,死背硬记的对于你开发没有作用,而是去理解它就行。前端只关心 URL、headers 和 data,接下来也围绕着它们展开。了解 HTTP 请求可以看看:https://developer.mozilla.org…
1. 了解 URL
URL 比较简单,就简单介绍一下,将 URL 分为主要的 3 部分:
router,路由。路由地址可不能错,这就跟收件地址一样,填错收货的就不是既定的那个人了。
search,查询字符串,就是? 后面的字符串,以键值对的形式通过“&”连接,例如:“?key1=value1&key2=value2”。查询字符串就是发送到后台的数据,跟普通的 post 请求相比,get 请求以明文的形式存储在访问历史,浏览器和路由器都很容易查得到,容易泄露,所以不建议用 get 请求;其次一般浏览器都有限制 URL 的长度,所以不适合发送大数据量的数据。
hash,哈希值或者称为锚,是 #后面的字符串,一般作为单页应用的路由地址,或者文档的锚。
2. 前端常用的 headers
1.Content-Type(重要)
告诉客户端,用什么形式前端的数据发送到后台:
application/x-www-form-urlencoded
最常见的方式以键值对的字符串传输 (类似 URL 的 search),但不能传输文件,几乎所有的 ajax 框架都是默认以此种方式发送。发送到后台的数据见下图:
multipart/form-data, 这种方式会以键值对的形式通过分隔符链接,以字符串给后台,可以传输文件,也可以传输普通数据。
常用场景:
// 源生的 form 提交可设置 enctype=”multipart/form-data”,一般表单中有文件会自动设为该值
<form action=”post” enctype=”multipart/form-data”></form>
// ajax 请求, 通过 formdata 对象来达成此目的
const formdata = new new FormData();
formdata.append(“key”,”value”)
$.ajax({
…
data: formdata,
processData: false, // 取消对数据的预处理,因为 formdata 不需要预处理
headers: {
“Content-Type”: undefined // 客户端会自动给它设置正确的值,不要设为 multipart/form-data,这样设的后果会导致分隔符不正确
},
…
})
如果在抓包确认划线的一致的话就是正确发送过去了。
text/plain
这个很少会用到了,普通文本,可以是任意数据,除了文件。
binary
二进制流,仅限一个文件。
Data-Type
告诉后台你希望返回什么类型的数据, 如 xml,html,script,json,jsonp,text 等,或者你跟后台约定的也可。但是实际返回的并非跟预期一致,还是由后台决定的。
自定义 header
如果跟后台有约定 header,如 token 等, 也可传到后台。
headers[“token”] = “MD5KEY”;
CORS 跨域
跨域问题的根本问题就是同源策略,旨在防止网站被攻击,这里不做赘述。CORS 是后台的工作,但前端工程师还是要了解 CORS,这样才有后台抬杠的资本。以下是后台 response 配置 CORS 的 headers,如果后台不懂,请让他了解了解 CORS。
Access-Control-Allow-Origin
简单说,允许跨域访问的 host,必须设置,否则不允许跨域。
// 如需允许所有资源都可以访问您的资源,您可以如此设置:
Access-Control-Allow-Origin: *
// 如需允许 https://developer.mozilla.org 访问您的资源,您可以设置:
Access-Control-Allow-Origin: https://developer.mozilla.org
Access-Control-Allow-Credentials
如果想跨域传输 cookies, 需要 Access-Control-Allow-Credentials 与 XMLHttpRequest.withCredentials 或 Fetch API 中的 Request() 构造器中的 credentials 选项结合使用。Credentials 必须在前后端都被配置(即 the Access-Control-Allow-Credentials header 和 XHR 或 Fetch request 中都要配置)才能使带 credentials 的 CORS 请求成功。
Access-Control-Request-Method
允许跨域的请求的方法。
Access-Control-Allow-Methods: POST, GET, OPTIONS
Access-Control-Allow-Headers
response 的 header 中 Access-Control-Allow-Headers 用于 preflight request(即会在实际请求发送之前先发送一个 option 请求)中,列出了将会在正式请求的 Access-Control-Expose-Headers 字段中出现的首部信息。
简单首部,如 simple headers、Accept、Accept-Language、Content-Language、Content-Type(只限于解析后的值为 application/x-www-form-urlencoded、multipart/form-data 或 text/plain 三种 MIME 类型(不包括参数)),它们始终是被支持的,不需要在这个首部特意列出。
preflight request–options 请求
很多人在抓包时会很郁闷怎么会无端端多出了一个 OPTIONS 请求,请不要奇怪,这只是 CORS 策略的预检请求,就像你要去跟别人借个东西,要先问问对方肯不肯一样。
什么情况下回发送 OPTIONS 请求?
简单的说,就是没有自定义 headers,Content-Type 的值属于下列之一:application/x-www-form-urlencoded,multipart/form-data,text/plain。如果产生 OPTIONS 请求要后台去响应它,允许它跨域。https://www.jianshu.com/p/b55… 可以参考篇文章。
抓包和问题分析
PS: 我主要使用 Chrome 的 DevTools 工具
确保发送的数据没问题
不要相信你的代码,以抓包工具的为准!!!!!要相信如果抓包的数据有问题,那么就是你的代码有问题。不要相信你的代码,以抓包工具的为准!!!!!要相信如果抓包的数据有问题,那么就是你的代码有问题。不要相信你的代码,以抓包工具的为准!!!!!要相信如果抓包的数据有问题,那么就是你的代码有问题。
URL 确保跟后台约定的一致
headers 要尤其关注 Content-Type,GET 请求没有 Content-Type.
请求的参数是否正确
后台返回什么了?
如果你确认你发送的数据没问题,那么该看看后台响应了什么,如果响应的数据有问题,那么是后台的责任。如果是跨域的要查看有没有响应 CORS 的请求头。
HTTP STATUS