ajax携带cookie

  目录

ajax同域和跨域情况下携带cookie问题

ajax携带cookie

这是一个老生常谈的问题,但是时间长了总容易忘掉,今天记录下来,以便下次方便记起来。

首先,今天我遇到了一个坑,chrome浏览无论是同域还是跨域状态下,浏览器request headers里居然都不显示,刚开始我还以为是设置错了,后来发现其他浏览器都显示,我想有可能是chrome浏览器安全考虑吧,但是,这并不影响后台接收,只是不显示而已。

同域下无可厚非,什么都不用做就会带上cookie。

跨域下的设置:
浏览器端,需要设置withCredentials为true

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// 原生方式
var xhr = new XMLHttpRequest();
xhr.open('GET', 'http://example.com/', true);
xhr.withCredentials = true;

// jquery方式
$.ajax({
url: "http://192.168.252.12:3006/post_form",
type: 'POST',
xhrFields: {
withCredentials: true // 这里设置了withCredentials
},
success: function(data) {
console.log(data)
},
error: function(err) {
console.error(err)
}
});

// axios方式
import axios from 'axios';
axios.defaults.withCredentials = true;

再来说说后端的设置,以nodejs的express为例:

1
2
3
// 返回头设置
res.header("Access-Control-Allow-Origin", "http://localhost:9000"); // 注意,这里不能写*,应该是具体的地址
res.header("Access-Control-Allow-Credentials", "true");

最后附上demo代码:
前端

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<script src="jquery.js"></script>
</head>
<body>
ajax cookie demo
</body>
<script>
$.ajax({
url: "http://192.168.252.12:3006/post_form",
type: 'POST',
xhrFields: {
withCredentials: true // 这里设置了withCredentials
},
success: function(data) {
console.log(data)
},
error: function(err) {
console.error(err)
}
});
</script>
</html>

后端

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
var express = require('express');
var app = express();
var multiparty = require('multiparty');
var bodyParser = require('body-parser');
var cookieParser = require('cookie-parser');

app.set('port',process.env.PORT || 3006); //设置端口

app.all('*', function(req, res, next) {
res.header("Access-Control-Allow-Origin", "http://localhost:9000");
res.header("Access-Control-Allow-Credentials", "true");

res.header("Access-Control-Allow-Headers", "client-token,Content-Type,Content-Length, Authorization, Accept,X-Requested-With");
res.header("Access-Control-Allow-Methods","PUT,POST,GET,DELETE,OPTIONS");
res.header("X-Powered-By",' 3.2.1');
if(req.method=="OPTIONS") res.send(200); //让options请求快速返回
else next();
});

//使用static中间件 制定public目录为静态资源目录,其中资源不会经过任何处理
app.use(express.static(__dirname + '/public'));
app.use(bodyParser.json()); // for parsing application/json
app.use(bodyParser.urlencoded({ extended: true })); // for parsing application/x-www-form-urlencoded
app.use(cookieParser()); // cookie解析

app.post('/post_form',function(req,res){
var data = {
name: req.body.name,
info: req.body.info,
hostName: req.hostname
};
res.cookie("add", 'test456', {maxAge: 900000, httpOnly: true}); // 设置cookie
console.log('cookie->' + req.cookies.add); // 读取cookie
res.send(data);
});

app.listen(app.get('port'), function () {
console.log( '服务器启动完成,端口为: '+app.get('port') );
});