Javascript 使用CORS请求设置Cookie
几天来我一直在努力解决这个问题。在CORS请求上设置cookie。我看到过相互矛盾的文章和答案,有人说只要XHR请求的Javascript 使用CORS请求设置Cookie,javascript,node.js,ajax,cookies,cross-domain,Javascript,Node.js,Ajax,Cookies,Cross Domain,几天来我一直在努力解决这个问题。在CORS请求上设置cookie。我看到过相互矛盾的文章和答案,有人说只要XHR请求的和credentials设置为true,并且服务器发送适当的头,浏览器就应该尊重set Cookie头。然而,在我的测试中,情况并非如此 示例代码: index.js(Node.js服务器) cookies.html 曲奇测试 去拿饼干! (功能(){ document.querySelector(“.getCookie”).addEventListener(“单击”,函数(e
和credentials
设置为true,并且服务器发送适当的头,浏览器就应该尊重set Cookie
头。然而,在我的测试中,情况并非如此
示例代码:
index.js(Node.js服务器)
cookies.html
曲奇测试
去拿饼干!
(功能(){
document.querySelector(“.getCookie”).addEventListener(“单击”,函数(e){
控制台日志(“测试”);
var req=新的XMLHttpRequest();
请求打开(“获取”http://localhost:3999/cookie“,对);
req.onload=函数(){
控制台日志(请求响应文本);
};
req.withCredentials=true;
请求发送();
});
}());
我已经在Firefox开发者版和Chrome上测试过,除非直接访问页面,否则不会设置cookie
让Cookie在CORS请求上工作,我缺少什么吗?不明显的是,服务器设置的Cookie,至少在CORS请求中,并且可能(可能)在所有请求中,都限制在与服务器相同的域内 index.js(Node.js服务器) cookies.html
曲奇测试
去拿饼干!
(功能(){
document.querySelector(“.getCookie”).addEventListener(“单击”,函数(e){
控制台日志(“测试”);
var req=新的XMLHttpRequest();
//请求成功,但不会设置cookie!
//请求打开(“获取”http://localhost:3999/cookie“,对);
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
//但是,假设此页面处于打开状态,则此行将起作用
//同一域或同一域的子域。
//(例如test.example.dev和api.example.dev)
//只要访问控制Allow Origin标头为
//正确设置为允许域。
请求打开(“获取”http://api.example.dev:3999/cookie“,对);
req.onload=函数(){
控制台日志(请求响应文本);
};
req.withCredentials=true;
请求发送();
});
}());
我认为,服务器(而不是clent)必须设置cookie才能使其正常工作。否则,您可以在任何地方设置Cookie。此外,如果跨源请求在响应中设置Cookie,则会为其自己的域而不是您的域设置Cookie。@PoulBak我应该指定index.js
是一个节点文件,以演示我用来测试它的服务器。所以是服务器设置cookie。@Pointy是在CORS请求中发送回cookie时忽略的域
参数吗?或者,Domain
参数是否仅限于同一来源?Domain被明确限制为服务器自己的域,它无法设置第三方cookie,即使使用CORS也是如此。
const http = require('http');
const fs = require('fs');
// Pretty colors
const colors = {
purple: '\033[95m',
orange: '\033[93m',
blue: '\033[97m',
underline: '\033[4m',
bold: '\033[1m',
reset: '\033[0m'
}
const server = http.createServer(function (req, res) {
//Console logs to verify what's getting hit.
console.log(colors.purple + colors.underline + 'Hit it!' + colors.reset);
console.log(colors.orange + colors.bold + 'url:' + colors.reset, req.url);
if (/\/cookie/.test(req.url)) {
console.log(colors.blue + 'We need to cook(ie) Jesse\n' + colors.reset);
// Generate a random string in a rather convoluted way.
var randomStr = Math.floor(Math.random() * Number.MAX_SAFE_INTEGER).toString(36) +
Math.floor(Math.random() * Number.MAX_SAFE_INTEGER).toString(36) +
Math.floor(Math.random() * Number.MAX_SAFE_INTEGER).toString(36);
randomStr = new Buffer(randomStr.toString(), 'binary').toString('base64');
// All .dev domains pointed to localhost via dnsmasq, though a hosts file
// Update should also do the trick.
res.writeHead(200, {
'Set-Cookie': 'ajaxTestCookie=cookie' + randomStr + '; Domain=.example.dev; HttpOnly',
'Access-Control-Allow-Origin': 'http://example.dev:3999',
'Access-Control-Allow-Credentials': 'true',
'Access-Control-Allow-Methods': 'GET, POST',
'Access-Control-Allow-Headers': 'Content-Type, Set-Cookie, *'
});
return res.end('OK!');
}
console.log(colors.blue + 'We\'re having fun at the HTML!\n' + colors.reset);
// Send out html file.
fs.readFile('./cookies.html', function (err, data) {
if (err) {
res.writeHead(500);
return res.end('Failure to launch!');
}
res.end(data.toString());
});
});
server.listen(3999);
<html>
<head>
<title>Cookie Test</title>
</head>
<body>
<button class="getCookie">Get Cookies!</button>
<script>
(function() {
document.querySelector(".getCookie").addEventListener("click", function(e) {
console.log("test");
var req = new XMLHttpRequest();
req.open("GET", "http://localhost:3999/cookie", true);
req.onload = function() {
console.log(req.responseText);
};
req.withCredentials = true;
req.send();
});
}());
</script>
</body>
</html>
const http = require('http');
const fs = require('fs');
// Pretty colors
const colors = {
purple: '\033[95m',
orange: '\033[93m',
blue: '\033[97m',
underline: '\033[4m',
bold: '\033[1m',
reset: '\033[0m'
}
const server = http.createServer(function (req, res) {
//Console logs to verify what's getting hit.
console.log(colors.purple + colors.underline + 'Hit it!' + colors.reset);
console.log(colors.orange + colors.bold + 'url:' + colors.reset, req.url);
if (/\/cookie/.test(req.url)) {
console.log(colors.blue + 'We need to cook(ie) Jesse\n' + colors.reset);
// Generate a random string in a rather convoluted way.
var randomStr = Math.floor(Math.random() * Number.MAX_SAFE_INTEGER).toString(36) +
Math.floor(Math.random() * Number.MAX_SAFE_INTEGER).toString(36) +
Math.floor(Math.random() * Number.MAX_SAFE_INTEGER).toString(36);
randomStr = new Buffer(randomStr.toString(), 'binary').toString('base64');
// All .dev domains pointed to localhost via dnsmasq, though a hosts file
// Update should also do the trick.
res.writeHead(200, {
'Set-Cookie': 'ajaxTestCookie=cookie' + randomStr + '; domain=.example.dev; HttpOnly',
'Access-Control-Allow-Origin': 'http://example.dev:3999',
'Access-Control-Allow-Credentials': 'true',
'Access-Control-Allow-Methods': 'GET, POST',
'Access-Control-Allow-Headers': 'Content-Type, Set-Cookie, *'
});
return res.end('OK!');
}
console.log(colors.blue + 'We\'re having fun at the HTML!\n' + colors.reset);
// Send out html file.
fs.readFile('./cookies.html', function (err, data) {
if (err) {
res.writeHead(500);
return res.end('Failure to launch!');
}
res.end(data.toString());
});
});
server.listen(3999); // api.example.dev:3999, for example
<html>
<head>
<title>Cookie Test</title>
</head>
<body>
<button class="getCookie">Get Cookies!</button>
<script>
(function() {
document.querySelector(".getCookie").addEventListener("click", function(e) {
console.log("test");
var req = new XMLHttpRequest();
// Request succeeds, but cookie will not be set!
// req.open("GET", "http://localhost:3999/cookie", true);
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
// This line, however, will work, assuming this page is on
// the same domain, or a subdomain of the same domain.
// (For example test.example.dev and api.example.dev)
// As long as the Access-Control-Allow-Origin Header is
// properly set to allow the domain.
req.open("GET", "http://api.example.dev:3999/cookie", true);
req.onload = function() {
console.log(req.responseText);
};
req.withCredentials = true;
req.send();
});
}());
</script>
</body>