[英]$http response Set-Cookie not accessible
I'm currently writing an angularjs frontend to my backend, and I'm running into a somewhat common issue:我目前正在为我的后端编写一个 angularjs 前端,我遇到了一个常见的问题:
Server sends a cookie back in a response, but is completely ignored by angular.js (can't even print out the 'Set-Cookie' value).服务器在响应中发回 cookie,但被 angular.js 完全忽略(甚至无法打印出“Set-Cookie”值)。
I've tried reading我试过阅读
Set-Cookie in HTTP header is ignored with AngularJS<\/a>
AngularJS 忽略 HTTP 标头中的 Set-Cookie<\/a>
Angularjs $http does not seem to understand "Set-Cookie" in the response<\/a>
Angularjs $http 似乎不理解响应中的“Set-Cookie”<\/a>
$http.post('/services/api/emailLogin',
sanitizeCredentials(credentials),
{
withCredentials: true
}).success(function(data, status, header) {
console.log(header('Server'));
console.log(header('Set-Cookie'));
console.log(header('Access-Control-Allow-Headers'));
console.log(header('Access-Control-Allow-Methods'));
console.log(header);
}).then(
function(response) {
console.log(response);
return response.data;
});
I looked inside $httpBackend
source code: 我查看了
$httpBackend
源代码:
xhr.onreadystatechange = function() {
// some code
if (xhr && xhr.readyState == 4) {
var responseHeaders = null,
response = null;
if(status !== ABORTED) {
responseHeaders = xhr.getAllResponseHeaders();
// some code
It uses XMLHttpRequest#getAllResponseHeaders
to get the response headers. 它使用
XMLHttpRequest#getAllResponseHeaders
来获取响应头。
After a little search I found this question: xmlHttp.getResponseHeader + Not working for CORS 经过一番搜索,我发现了这个问题: xmlHttp.getResponseHeader +不适用于CORS
Which made me realize that XHR by it's specification, doesn't support SET-COOKIE
, so it have nothing to do with angular.js in particular. 这让我意识到XHR的规格,不支持
SET-COOKIE
,所以它与angular.js无关。
http://www.w3.org/TR/XMLHttpRequest/#the-getallresponseheaders%28%29-method http://www.w3.org/TR/XMLHttpRequest/#the-getallresponseheaders%28%29-method
4.7.4 The getAllResponseHeaders() method
4.7.4 getAllResponseHeaders()方法
Returns all headers from the response, with the exception of those whose field name is Set-Cookie or Set-Cookie2 .
返回响应中的所有标头,但字段名称为Set-Cookie或Set-Cookie2的标头除外 。
$cookies
: $cookies
: It's a different module so you must add it to your scripts 它是一个不同的模块,因此您必须将其添加到脚本中
<script src="angular.js"></script>
<script src="angular-cookies.js"></script>
And add it to the module dependencies: 并将其添加到模块依赖项:
var app = angular.module('app',['ngCookies']);
Then just use it like so: 然后就像这样使用它:
app.controller('ctrl', function($scope, $http , $cookies, $timeout){
$scope.request = function(){
$http.get('/api').then(function(response){
$timeout(function(){
console.log($cookies.session)
});
})
}
})
I use $timeout
because $cookies
only synchronize with browser's cookies after a digest. 我使用
$timeout
因为$cookies
仅在摘要后与浏览器的cookie同步。
Do you actually need to read the cookie in Angular, or is it enough if it gets set and passed back on further requests by the browser? 你是否真的需要在Angular中读取cookie,或者它是否足够,如果它被设置并传回浏览器的进一步请求? While I wasn't able to get the former working, I was able to get the latter working pretty quickly with a very similar configuration.
虽然我无法让前者工作,但我能够以非常相似的配置让后者快速工作。 (In particular, I was not able to use
$cookies
as @Ilan recommended. It returned nothing.) (特别是,我无法使用
$cookies
作为@Ilan推荐。它什么也没有返回。)
First things first, on the Angular side configure the $httpProvider
to send withCredentials
by default: 首先,在Angular端配置
$httpProvider
默认发送withCredentials
:
app.config(['$httpProvider', function($httpProvider) {
$httpProvider.defaults.withCredentials = true;
}]);
That's all you have to do in Angular. 这就是你在Angular所要做的一切。 Note that, at this point, if you attempt to read
$cookies
it will still not be able to see the cookie, but it is saved and will be passed with future AJAX calls. 请注意,此时,如果您尝试读取
$cookies
它仍然无法看到cookie,但它会被保存并将在未来的AJAX调用中传递。
Then, on the server, you need to provide a specific domain (or a set of domains) allowed under CORS, along with the Access-Control-Allow-Credentials
header. 然后,在服务器上,您需要提供CORS下允许的特定域(或一组域)以及
Access-Control-Allow-Credentials
标头。 My backend is Flask in Python with Flask-Restful and it looks like this: 我的后端是Flask in Python with Flask-Restful ,它看起来像这样:
import Flask
from flask_restful import Api
app = Flask(__name__)
api = Api(app)
api.decorators = [cors.crossdomain(origin='http://localhost:8100', credentials=True)]
That's all it took. 这就是全部。 Now Angular (or, rather, the browser) sets the cookie and returns it with future requests completely transparently!
现在,Angular(或者更确切地说,浏览器)设置cookie并将其与未来的请求完全透明地返回!
(The same point is made here: https://stackoverflow.com/a/19384207/2397068 .) (同样的观点在这里: https : //stackoverflow.com/a/19384207/2397068 。)
In Angular 1.3.14 it doesn't work anymore. 在Angular 1.3.14中它不再起作用。
I had the same problem. 我有同样的问题。 I am using $resource and declared withCredentials: true.
我正在使用$ resource并声明withCredentials:true。
var fooRes = $resource('/address/exemple',
{},
{
bar: {
method: 'POST',
withCredentials: true,
}
}
);
fooRes.bar({
"stuff" : "lorem"
}).$promise.then(function(){
//callback
})
or you can set the header "Access-Control-Allow-Credentials", "true". 或者您可以设置标题“Access-Control-Allow-Credentials”,“true”。
Now the cookie will be saved and you can get using $cookie. 现在cookie将被保存,您可以使用$ cookie。
Hope it will help. 希望它会有所帮助。
您需要修改.htaccess文件以允许读取标头。
Header set Access-Control-Allow-Headers Content-Type
Set 'access-control-expose-headers', '*'
设置
'access-control-expose-headers', '*'
Example with Node API节点 API 示例
router.get('/your-route', async (req, res) => {
//..
res.setHeader('access-control-expose-headers', '*' );
//..
})
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.