前后端分离的web项目,ajax跨域请求后端携带cookie

2019独角兽企业重金招聘Python工程师标准>>> hot3.png

    在做web项目时,遇到前后端分离的项目,第一个要解决的就是跨域问题,然后就是保存用户信息的session和cookie的问题,通常使用二者的结合使用。然而在实际的开发中,对于前后端分离的项目,每次ajax请求无法携带cookie到后端,导致每次都会新创建一个session,而无法获取login时保存的信息。

    先来说一下代码的解决方法:(这里是maven项目,使用的是spring mvc)

一、后端;

    后端自定义实现了servlet 的filter,也就是 解决跨域问题的通用方法之一Cross;

    @Override
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
			throws IOException, ServletException {
		// TODO Auto-generated method stub
		HttpServletResponse resp = (HttpServletResponse) response;
		HttpServletRequest rep = (HttpServletRequest) request;
		
		resp.addHeader("Access-Control-Allow-Origin", rep.getHeader("Origin"));
		//允许跨域请求中携带cookie		
		resp.addHeader("Access-Control-Allow-Credentials", "true");
		// 如果存在自定义的header参数,需要在此处添加,逗号分隔
		resp.addHeader("Access-Control-Allow-Headers", "authorization,Origin, No-Cache, X-Requested-With, "
				+ "If-Modified-Since, Pragma, Last-Modified, Cache-Control, Expires, " + "Content-Type, X-E4M-With");
		resp.addHeader("Access-Control-Allow-Methods", "GET, POST, OPTIONS");

		chain.doFilter(request, response);
	}

二、前端:

ajax请求添加以下参数:

crossDomain: true,
xhrFields: {
    withCredentials: true
},

整体ajax为:

      $.ajax({
        url : patl,
        type: "POST",
        crossDomain: true,
        xhrFields: {
            withCredentials: true
        },
        success : function(result) {
           alert("success");
        }
    });

 

下面描述一下上面的代码;

首先ajax 添加  withCredentials: true  ,这是指定这个请求应该发送凭据。

而 crossDomain: true, 则是解决跨域配置。

对应的后端配置,要在filter 的 header 中添加 Access-Control-Allow-Credentials 为true,这是允许跨域请求携带cookie,

这是还需要设置Access-Control-Allow-Origin  ,若 这个设置为“*”,则 当请求发出时,浏览器就报错如下 : Response to preflight request doesn't pass access control check: A wildcard '*' cannot be used in the 'Access-Control-Allow-Origin' header when the credentials flag is true. Origin 'null' is therefore not allowed access. The credentials mode of an XMLHttpRequest is controlled by the withCredentials attribute.

这是因为这样设置和前端跨域请求携带cookie产生了冲突,这时把“*” 换作前端项目的部署服务器的ip即可。

这样更改若后端项目只和web端有交互还好(并且前后端不分离,分离的话前端ip是变化的),若又和app或是别的有交互的话,就会出现问题,请求无法携带凭证。

因为在做项目时刚好后端既要和web端有交互,又与app端有交互,so,以上方法无法解决。

查阅资料有的说把“*”换作null 就可以了,但 在我这 也不好使,

最后通过查阅资料并和同事探讨,把“*” 换成rep.getHeader("Origin"),这样每次请求获取请求的Origin,无论前端怎么变化,但在同一个浏览器窗口中ip是不变的,所以这样相当于动态设置Origin,完美解决问题。

通过上述的配置,针对前后端分离的项目,每次ajax 请求可以携带cookie了,这样在同一个浏览器窗口中每次请求到后端的session就变成了一个,这样就可以做一些token验证之类的操作了(若每次请求不是一个session,则需要查看登录时 前端是否自动写入了cookie,若没有写入,则需要手动将sessionId写入到cookie中,key=“JSESSIONID” ,vlue为第一次登录请求返回来的sessionId)。

 

转载于:https://my.oschina.net/qinghang/blog/1608792

你可能感兴趣的:(前后端分离的web项目,ajax跨域请求后端携带cookie)