使用CORS请求设置Cookie

我一直在试图解决这个问题几天。 在CORS请求上设置Cookie。 我见过有冲突的文章和答案,有人说,只要XHR请求将withCredentials设置为true,并且服务器发送适当的头文件,浏览器应该尊重Set-Cookie头文件。 不过,在我的testing中,情况并非如此。

示例代码:

index.js(Node.js服务器)

 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); 

cookies.html

 <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> 

我已经尝试在Firefox开发者版和Chrome上进行testing,除非直接访问页面,否则不会设置Cookie。

有什么我错过让cookiesCORS请求工作?

不明显的是服务器设置的cookie,至less在CORS请求中,可能(可能)在所有请求中被限制在与服务器相同的域中。

index.js(Node.js服务器)

 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 

cookies.html

 <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>