session
php的session比cookie安全,这是好多人知道的常识。session的数据是存放在服务端的,那么程序是如何取到对应的session呢?
那是因为每一个session都有一个身份证号,那就是session id。这个东西一般情况下,服务器会发送给客户端,客户端将它放在cookie里。
cookie是存在跨域问题的,什么叫跨域呢?a.domain.com下创建的cookie,在b.domain.com下是无法使用的,我们需要进行跨域设置。
axios
用过vue开发前后端分离程序的人对axios相比都不陌生了,js前后端分离,如果前后端用两个域名,也存在跨域问题。
跨域是个老生常谈的问题了,特别是前后端分离以后。解决前后端分离其实没有想象中的那么难,主要是明白其中的道理。首先先了解介个基本知识。
session
php的session比cookie安全,这是好多人知道的常识。session的数据是存放在服务端的,那么程序是如何取到对应的session呢?
那是因为每一个session都有一个身份证号,那就是session id。这个东西一般情况下,服务器会发送给客户端,客户端将它放在cookie里。
cookie是存在跨域问题的,什么叫跨域呢?a.domain.com下创建的cookie,在b.domain.com下是无法使用的,我们需要进行跨域设置。
axios
用过vue开发前后端分离程序的人对axios相比都不陌生了,js前后端分离,如果前后端用两个域名,也存在跨域问题。
解决跨域
前端请求后端接口跨域很容易解决,服务端设置好返回头就可以了,如下:
1 2 3 4 5 6 7 8 9 10 11 12
| if ($request_method = 'OPTIONS') { add_header 'Access-Control-Allow-Origin' '$http_origin'; add_header 'Access-Control-Allow-Credentials' 'true'; add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE, OPTIONS'; add_header 'Access-Control-Allow-Headers' 'Origin, DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type, Accept, authKey, sessionId, business,shop'; #add_header 'Access-Control-Allow-Headers' '*'; add_header 'Access-Control-Max-Age' 1728000; add_header 'Content-Type' 'text/plain charset=UTF-8'; add_header 'Content-Length' 0;
return 204; }
|
发个全一点的
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| location / { if ($request_method = 'OPTIONS') { add_header 'Access-Control-Allow-Origin' '$http_origin'; add_header 'Access-Control-Allow-Credentials' 'true'; add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE, OPTIONS'; add_header 'Access-Control-Allow-Headers' 'Origin, DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type, Accept, authKey, sessionId, business,shop'; #add_header 'Access-Control-Allow-Headers' '*'; add_header 'Access-Control-Max-Age' 1728000; add_header 'Content-Type' 'text/plain charset=UTF-8'; add_header 'Content-Length' 0;
return 204; } if (!-e $request_filename) { rewrite ^(.*)$ /index.php?s=/$1 last; break; }
# First attempt to serve request as file, then # as directory, then fall back to displaying a 404. try_files $uri $uri/ =404; }
|
这样设置后,普通的ajax跨域请求基本就可以了,当然这里的location要根据你的实际情况,也有可能是location ~ \.php$
如果这写头信息无法满足,你也可以使用php的header函数重新设置header头。
经过上面的配置普通的跨域请求就可以正常执行了。接下来说一下携带cookie的跨域解决。
session跨域
上面说过session默认依赖cookie,所以我们创建session的时候要进行一下设置。
1
| ini_set('session.cookie_domain', '.domain.com');
|
创建session之前一定要有上面的设置,这样cookie就可以在a.domain.com和b.domain.com都有效。
后端支持了,还有前端,ajax请求默认不携带cookie信息,如何让它带上呢。很简单,ajax对象有一个withCredentials
属性,将它设置为true就可以了
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| var xhr = new XMLHttpRequest(); // IE8/9需用window.XDomainRequest兼容
// 前端设置是否带cookie xhr.withCredentials = true;
xhr.open('post', 'http://a.domain.com:8080/login', true); xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); xhr.send('user=admin');
xhr.onreadystatechange = function() { if (xhr.readyState == 4 && xhr.status == 200) { alert(xhr.responseText); } };
|
上面是普通ajax的实例,axios可以按下面的配置
1
| axios.defaults.withCredentials = true
|