今天分享一个关于预请求的, 我们先写一个接口, 新建 server.JS, 代码:
- const http = require('http');
- http.createServer(function (request, response) {
- response.writeHead(200, {
- 'Access-Control-Allow-Origin': '*'
- });
- response.end('welcome to options');
- }).listen(3000);
- console.log('listen port 3000');
然后 node server.JS, 打印出 listen port 300 表示启动成功, 接着写一个 Ajax 请求:
- $.Ajax({
- url: 'http://192.168.164.16:3000/',
- method: 'get',
- success: function (res) {
- console.log(res);
- }
- })
'Access-Control-Allow-Origin': ''是允许跨域, 当然, 一般不会用, 会设置某一个地址.
先明确一个概念, 预请求是浏览器的策略机制, 在真正发送请求之前, 会先进行一次预请求作用是用于试探性的服务器响应是否正确, 如果 options 获得的回应是拒绝性质的, 就会停止 post,get 等请求的发出, 或者报错.
在这里插入图片描述
会发起预请求有几个条件:
请求方法不是 GET,POST,HEAD
Content-Type 不是 text/plain,multipart/form-data,application/x-www-form-urlencoded
请求自定义了 header 字段的
上面三种情况都会发起预请求, 当我们使用 get,post,head 方法发起 Ajax 请求的时候, 用上面的接口测试, 确实不会发起预请求. 而且用这三个请求方法之外的都会报错, 跨域. 可以加允许跨域的方法:
'Access-Control-Allow-Methods': 'PUT'
接着 Ajax 发起 put 方法的请求, 就会有两次请求, 一次是预请求 options, 一次是请求成功:
在这里插入图片描述
在这里插入图片描述
接着测试一下 content-type, 修改请求:
- $.Ajax({
- url: 'http://192.168.164.16:3000/',
- method: 'get',
- contentType: 'text/plain',
- success: function (res) {
- console.log(res);
- }
- })
分别设置 contentType 为上面的三个, 发现也不会发起预请求 options:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
如果换成 JSON 的:
在这里插入图片描述
测试这个的时候要设置请求头:'Access-Control-Allow-Headers': '*'.
如果我们设置另外的 header:
- $.Ajax({
- url: 'http://192.168.164.16:3000/',
- method: 'get',
- headers: {
- 'X-Test': 'ok'
- },
- success: function (res) {
- console.log(res);
- }
- })
也是会发起预请求的.
在这里插入图片描述
最后发现, 上面三种情况之外, 会发起预请求的也都会报错跨域. 还有就是, 有些报跨域, 但是数据还是能得到, 只是浏览器认为是不安全的, 你可以在 network 看见数据但是你是拿不到数据的.
在这里插入图片描述
来源: http://www.jianshu.com/p/cdc722aee0e9