带cookie的异步ajax跨域请求问题

    ajax跨域携带cookie需要增加一个参数,xhrFields:{withCredentials:true},而且这个时候的cookie是种在服务端接口域里面的,而不是页面所在的域。

    服务端解决跨域问题的时候,会设置允许哪些Origin,Method,如果是跨域携带cookie的异步请求,这个允许的域只能是唯一的,不能使用通配符*,也不能同时设置多个域。同时还需要保证参数Access-Control-Allow-Credentials为true。

    下面通过示例演示:

    前端页面通过node框架koa库启动一个server,访问地址:http://localhost:3000/,默认会加载静态页面index.html。

    index.html




    
    
    
    cookie
    


    

    服务端使用springboot,解决跨域通过配置Filter:

    CookieController.java

package com.xxx.springboot.web;
import java.util.HashMap;
import java.util.Map;
import org.springframework.web.bind.annotation.CookieValue;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/cookie")
public class CookieController {
	
	@PostMapping("/test")
	public Map test(@CookieValue(value = "name")String name){
		Map map = new HashMap<>();
		System.out.println("getCookie "+name);
		map.put("code", 200);
		map.put("msg", "success");
		return map;
	}
}

    App.java 

package com.xxx.springboot;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;

import com.xxx.springboot.config.MyCorsFilter;

@SpringBootApplication
public class App {
    public static void main( String[] args ){
    	SpringApplication.run(App.class, args);
    }
    
    
    @SuppressWarnings({ "rawtypes", "unchecked" })
	@Bean
    public FilterRegistrationBean registerFilter() {
    	FilterRegistrationBean bean = new FilterRegistrationBean();
    	bean.addUrlPatterns("/*");
    	bean.setFilter(new MyCorsFilter());
    	return bean;
    }
}

    MyCorsFilter.java

package com.xxx.springboot.config;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class MyCorsFilter implements Filter {

	@Override
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
			throws IOException, ServletException {
		HttpServletResponse res = (HttpServletResponse) response;
		HttpServletRequest req = (HttpServletRequest)request;
		String origin = req.getHeader("Origin");
		System.out.println(origin);
		res.addHeader("Access-Control-Allow-Origin", "*");
		res.addHeader("Access-Control-Allow-Credentials", "true");
		chain.doFilter(request, response);
	}

}

   1、 准备cookie,这个动作需要在http://localhost:8080域上完成:

    带cookie的异步ajax跨域请求问题_第1张图片 

     虽然访问地址会有问题,因为没有静态页面可以加载,但是种个cookie还是可以的。

    2、访问前端页面,发起ajax跨域请求:

    带cookie的异步ajax跨域请求问题_第2张图片

    点击页面按钮,报错。

    报错详细信息:

Access to XMLHttpRequest at 'http://localhost:8080/cookie/test' from origin 
'http://localhost:3000' has been blocked by CORS policy: The value of the 'Access-Control-
Allow-Origin' header in the response must not be the wildcard '*' when the request's 
credentials mode is 'include'. The credentials mode of requests initiated by the 
XMLHttpRequest is controlled by the withCredentials attribute.

    3、我们修改Filter的内容,让允许的域是http://localhost:3000,而不是所有域*。

    带cookie的异步ajax跨域请求问题_第3张图片 

    访问正常,控制台也不报错。

    在Filter中设置允许的Origin时,可以不用写死请求域,可以通过request获取请求域,然后设置响应头的Origin。

@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
			throws IOException, ServletException {
	HttpServletResponse res = (HttpServletResponse) response;
	HttpServletRequest req = (HttpServletRequest)request;
	String origin = req.getHeader("Origin");
	//res.addHeader("Access-Control-Allow-Origin", "http://localhost:3000");
	res.addHeader("Access-Control-Allow-Origin", origin);
	res.addHeader("Access-Control-Allow-Credentials", "true");
	chain.doFilter(request, response);
}

  携带cookie的异步跨域请求,最容易出错的地方在于服务端设置的允许Origin是所有或者多个Origin。它只能允许唯一的Origin。 

 

你可能感兴趣的:(java,Web前端,ajax,cookie,credentials,origin,cors)