浏览器不存储 cookie
Browser doesn't store cookies
我正在从 Laravel 应用程序 (http://backend.local
) 向 Vue SPA (http://frontend.local:8080
) 发送 Cookie:
Laravel 侧(虚拟路由)
//api routes
Route::post('login', function () {
setcookie("name", 'value', time()+3600, "/", ".local");
return response('ok');
});
Vue 端
axios.post('//backend.local/api/login')
.then(response => {
console.log(response)
}).catch(error => {
})
回复Headers:
HTTP/1.1 200 OK
Date: Mon, 21 May 2018 09:42:35 GMT
Server: Apache
Set-Cookie: name=value; expires=Mon, 21-May-2018 10:42:36 GMT; Max-Age=3600; path=/; domain=.local
Cache-Control: no-cache, private
Access-Control-Allow-Origin: http://frontend.local:8080
Vary: Origin
X-RateLimit-Limit: 60
X-RateLimit-Remaining: 59
Content-Length: 2
Keep-Alive: timeout=10, max=100
Connection: Keep-Alive
Content-Type: text/html; charset=UTF-8
但是浏览器存储中没有Cookies(开发者控制台中的应用程序选项卡)。
怎么了?
更新:我认为问题是 http://frontend.local:8080
中有端口号。我可以从 url 中删除端口号吗?
由于这是一个 CORS 调用,您需要将 setCredentials
设置为 true
。这是标准行为:默认情况下标准 CORS 请求不发送或设置任何 cookie。
withCredentials
属性 将在请求中包含来自其他域的任何 cookie,并设置来自其他域的任何 cookie。
因此您的 Vue.js
代码将是:
axios.defaults.withCredentials = true
axios({
method: 'POST',
url: '//backend.local/api/login',
// THIS IS IMPORTANT
withCredentials: true
})
.then(response => {
console.log(response)
}).catch(error => {})
[编辑]:在 HTML Rocks 阅读更多关于 CORS 的信息。
如果没有帮助,请告诉我。
原答案
浏览器将自动拒绝任何不包含两个部分的域。所以使用 .local
根本不被认为是一个域。你至少需要两个级别。考虑下面我为演示相同内容而创建的烧瓶应用程序
from flask import Flask, request, make_response
app = Flask(__name__)
@app.route("/")
def index():
resp = make_response()
resp.set_cookie('value1', ".frontend.local", domain=".frontend.local")
resp.set_cookie('value2', "frontend.local", domain="frontend.local")
resp.set_cookie('value3', ".local", domain=".local")
return resp
app.run(debug=True)
现在通过 curl 进行测试
$ curl -v frontend.local:5000
* Rebuilt URL to: frontend.local:5000/
* Trying 127.0.0.1...
* TCP_NODELAY set
* Connected to frontend.local (127.0.0.1) port 5000 (#0)
> GET / HTTP/1.1
> Host: frontend.local:5000
> User-Agent: curl/7.54.0
> Accept: */*
>
* HTTP 1.0, assume close after body
< HTTP/1.0 200 OK
< Content-Type: text/html; charset=utf-8
< Set-Cookie: value1=.frontend.local; Domain=.frontend.local; Path=/
< Set-Cookie: value2=frontend.local; Domain=frontend.local; Path=/
< Set-Cookie: value3=.local; Domain=.local; Path=/
< Content-Length: 0
< Server: Werkzeug/0.14.1 Python/3.6.5
< Date: Tue, 29 May 2018 12:58:20 GMT
<
* Closing connection 0
当您在浏览器中导航时,您可以看到带 Domain=.local
的 cookie 被丢弃,但其余 2 保留
稍后您可以看到两个cookie都已发送到同一页面的重新加载
更新 1:2018 年 5 月 30 日
由于您使用的是 2 个不同的域,因此您应该使用 frontend.local.com
和 backend.local.com
,并且应该将 cookie 与域一起返回为 .local.com
,以便 backend
和frontend
作为 local.com
的子域。然后 frontend.local.com
通过域共享获取 backend.local.com
设置的 cookie,因为 cookie 域设置为 .local.com
我正在从 Laravel 应用程序 (http://backend.local
) 向 Vue SPA (http://frontend.local:8080
) 发送 Cookie:
Laravel 侧(虚拟路由)
//api routes
Route::post('login', function () {
setcookie("name", 'value', time()+3600, "/", ".local");
return response('ok');
});
Vue 端
axios.post('//backend.local/api/login')
.then(response => {
console.log(response)
}).catch(error => {
})
回复Headers:
HTTP/1.1 200 OK
Date: Mon, 21 May 2018 09:42:35 GMT
Server: Apache
Set-Cookie: name=value; expires=Mon, 21-May-2018 10:42:36 GMT; Max-Age=3600; path=/; domain=.local
Cache-Control: no-cache, private
Access-Control-Allow-Origin: http://frontend.local:8080
Vary: Origin
X-RateLimit-Limit: 60
X-RateLimit-Remaining: 59
Content-Length: 2
Keep-Alive: timeout=10, max=100
Connection: Keep-Alive
Content-Type: text/html; charset=UTF-8
但是浏览器存储中没有Cookies(开发者控制台中的应用程序选项卡)。 怎么了?
更新:我认为问题是 http://frontend.local:8080
中有端口号。我可以从 url 中删除端口号吗?
由于这是一个 CORS 调用,您需要将 setCredentials
设置为 true
。这是标准行为:默认情况下标准 CORS 请求不发送或设置任何 cookie。
withCredentials
属性 将在请求中包含来自其他域的任何 cookie,并设置来自其他域的任何 cookie。
因此您的 Vue.js
代码将是:
axios.defaults.withCredentials = true
axios({
method: 'POST',
url: '//backend.local/api/login',
// THIS IS IMPORTANT
withCredentials: true
})
.then(response => {
console.log(response)
}).catch(error => {})
[编辑]:在 HTML Rocks 阅读更多关于 CORS 的信息。
如果没有帮助,请告诉我。
原答案
浏览器将自动拒绝任何不包含两个部分的域。所以使用 .local
根本不被认为是一个域。你至少需要两个级别。考虑下面我为演示相同内容而创建的烧瓶应用程序
from flask import Flask, request, make_response
app = Flask(__name__)
@app.route("/")
def index():
resp = make_response()
resp.set_cookie('value1', ".frontend.local", domain=".frontend.local")
resp.set_cookie('value2', "frontend.local", domain="frontend.local")
resp.set_cookie('value3', ".local", domain=".local")
return resp
app.run(debug=True)
现在通过 curl 进行测试
$ curl -v frontend.local:5000
* Rebuilt URL to: frontend.local:5000/
* Trying 127.0.0.1...
* TCP_NODELAY set
* Connected to frontend.local (127.0.0.1) port 5000 (#0)
> GET / HTTP/1.1
> Host: frontend.local:5000
> User-Agent: curl/7.54.0
> Accept: */*
>
* HTTP 1.0, assume close after body
< HTTP/1.0 200 OK
< Content-Type: text/html; charset=utf-8
< Set-Cookie: value1=.frontend.local; Domain=.frontend.local; Path=/
< Set-Cookie: value2=frontend.local; Domain=frontend.local; Path=/
< Set-Cookie: value3=.local; Domain=.local; Path=/
< Content-Length: 0
< Server: Werkzeug/0.14.1 Python/3.6.5
< Date: Tue, 29 May 2018 12:58:20 GMT
<
* Closing connection 0
当您在浏览器中导航时,您可以看到带 Domain=.local
的 cookie 被丢弃,但其余 2 保留
稍后您可以看到两个cookie都已发送到同一页面的重新加载
更新 1:2018 年 5 月 30 日
由于您使用的是 2 个不同的域,因此您应该使用 frontend.local.com
和 backend.local.com
,并且应该将 cookie 与域一起返回为 .local.com
,以便 backend
和frontend
作为 local.com
的子域。然后 frontend.local.com
通过域共享获取 backend.local.com
设置的 cookie,因为 cookie 域设置为 .local.com