Heim > Fragen und Antworten > Hauptteil
我部署了一个angular工程 基于nodejs HTTP-server启动的,登陆url: http://localhost:9000/#/login
java工程项目 登陆url: http://localhost:8060/login
而我现在想在angular工程上完全只是调用java工程项目接口,而java项目现在准备纯碎只是为angular工程提供返回的json数据而已
在过程中出现跨域问题,我就在java工程上统一设置拦截器 在有新请求调用时都设置响应头:
response.setHeader("Access-Control-Allow-Origin" , "*" ); 即可解决跨域问题;
但是session丢失问题没解决
就是说我在angular项目调用登陆接口登陆,服务器端会创建一个session,并返回用户信息及权限信息等json数据 ,还有返回一个jsessionid到客户端;
如图所示:
登陆成功跳转至http://localhost:9000/#/home
但是我在首页点击左侧菜单执行java工程的其他接口时,比如说查询用户列表接口,它又被拦截掉,返回login接口,因为由请求头中找不到对应的jsessionid,相当于当前用户还处于未登陆状态
原理是:每次调用接口即发出新请求首先都会判断url上是否携带jsession,如果没有,则判断请求头的cookies中有jsession,如果已存在,则会传到后台,后台通过jsession获取对应session;可是如果jsession不存在或者通过jsession获取不到对应session的话,则会从新创建一个session
我想问一下就是怎么才能避免跨域调用接口导致session丢失呢?
迷茫2017-05-15 16:54:59
所以到现在都没有解决方案么。。
update
我解决了。后端是Java springboot,前端是angular,跨域json通信。
cors方式,配置一个corsfilter,代码如下:
package xxxxxx.component;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* Created by skyADMIN on 16/7/4.
*/
@Component
public class CORSFilter implements Filter {
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) res;
response.setHeader("Access-Control-Allow-Origin", request.getHeader("Origin"));
response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
response.setHeader("Access-Control-Max-Age", "3600");
response.setHeader("Access-Control-Allow-Headers", "x-requested-with");
response.setHeader("Access-Control-Allow-Credentials","true"); //是否支持cookie跨域
chain.doFilter(req, res);
}
public void init(FilterConfig filterConfig) {}
public void destroy() {}
}
这个配置在不少地方应该都能找到,不同的主要是两点:
1。response.setHeader("Access-Control-Allow-Credentials","true"); //是否支持cookie跨域
2。response.setHeader("Access-Control-Allow-Origin", request.getHeader("Origin"));
首先,配置了allow-credentials之后,如果allow-origin设为*,跨域时会报错说因为允许credentials,origin不能设为通配*,那所以设为简单的某个domain也是可以的,这种写法应该就是达到了任意domain都可以的效果吧。
然后angular部分也要设定个东西,举个栗子~
angular.module('frontendApp')
.controller('MainCtrl', function ($scope, $http, $location) {
var action = 'islogin';
$http.get(apiUrl + action, {withCredentials: true}).then(function (response) {
console.log(response);
if (response.data === 0) {
$location.url('login');
}
})
});
恩就是这个$http.get(url, {withCredentials: true})。
ok就酱。
高洛峰2017-05-15 16:54:59
Access-Control-Allow-Origin设置为*只是用来解决post请求跨域的问题的,cookie是没法跨域的,或者说只能跨2级域名,每个cookie都会有对应的域,写的时候可以指定为允许同一个1级域名下的所有2级域名访问,比如sf的
ringa_lee2017-05-15 16:54:59
既然是ng工程,你的载入页面应该只有一个,让java这边给你做一个入口,返回这个页面就好了。
引出的问题可能是你的angular模板如果都需要异步载入,也会跨域,一个方案是像你上面那样加上origin,另一个是直接将模板也打包成脚本直接加入进去