ajax请求携带自定义请求头header(跨域和同域)案例实战教程

1. ajax跨域请求(无cookie、无header)案例(java)

(1)启动一个java web项目,配置两个域名(host),czt.ming.com、czt.casicloud.com,java后端代码如下

注意:Access-Control-Allow-Origin

/**
	 * 
	    * @Title: getAjaxCross
	    * @Description: TODO(ajax请求,跨域)
	    * @param request
	    * @param response
	 */
	@RequestMapping(value ="/getAjaxCross",method= {RequestMethod.GET})
	public void getAjaxCross(HttpServletRequest request, HttpServletResponse response){
	    try {
	    	response.setCharacterEncoding("UTF-8");
	    	//设置允许多个域名允许跨域集合
	        String[] allowDomains = {"http://czt.casicloud.com", "http://czt.ming.com"};
	        Set allowOrigins = new HashSet(Arrays.asList(allowDomains));
	        String origin = request.getHeader("Origin");
	        if(allowOrigins.contains(origin)){
	            //设置允许跨域的配置:Access-Control-Allow-Origin: 响应头指定了该响应的资源是否被允许与给定的origin共享
	        	response.setHeader("Access-Control-Allow-Origin", origin);
	        }
		    //数据
		    Map<String, Object> resultMap = new HashMap<String, Object>();
		    resultMap.put("message", "ajax请求,跨域成功");
		    String result = JsonUtils.objectToJson(resultMap);
			response.getWriter().write(result);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

(2)前端页面代码如下:

//4.ajax跨域
         function getCookieAjaxCross() {
             $.ajax({
                 type:"get", 
                 url:"http://czt.ming.com/xxx/xxx/xxx/getAjaxCross",
                 async:true,
                 data:{},
                 dataType: 'json',
                 success: function(data) {
                     console.log(data);
                 }
             });
         }
         getCookieAjaxCross();

(3)测试ajax跨域请求:
通过http://czt.casicloud.com/xxx/xxx访问页面,js触发ajax跨域请求http://czt.ming.com/xxx/xxx/xxx/getAjaxCross,前端和后台如果不按照代码中配置相应参数会报各种跨域错误;

2. ajax跨域请求获取和创建cookie案例(java)

(1)启动一个java web项目,配置两个域名(host),czt.ming.com、czt.casicloud.com,java后端代码如下:

注意:Access-Control-Allow-Credentials和Access-Control-Allow-Origin

/**
	 * 
	    * @Title: getCookieAjax
	    * @Description: TODO(ajax请求,跨域传递cookie)
	    * @param request
	    * @param response
	 */
	@RequestMapping(value ="/getCookieAjax",method= {RequestMethod.GET})
	public void getCookieAjax(HttpServletRequest request, HttpServletResponse response){
	    try {
	    	response.setCharacterEncoding("UTF-8");
	    	response.setHeader("Access-Control-Allow-Credentials", "true");
	    	//设置允许多个域名允许跨域集合
	        String[] allowDomains = {"http://czt.casicloud.com", "http://czt.ming.com"};
	        Set allowOrigins = new HashSet(Arrays.asList(allowDomains));
	        String origin = request.getHeader("Origin");
	        if(allowOrigins.contains(origin)){
	            //设置允许跨域的配置:Access-Control-Allow-Origin: 响应头指定了该响应的资源是否被允许与给定的origin共享
	        	response.setHeader("Access-Control-Allow-Origin", origin);
	        }
	    	//获取cookie
	    	Cookie[] cookies = request.getCookies();
	    	//设置cookie
	    	Cookie cookie = new Cookie("access_token_ajax", UUID.randomUUID().toString());
	    	cookie.setPath("/");
	    	response.addCookie(cookie);
		    //数据
		    Map<String, Object> resultMap = new HashMap<String, Object>();
		    resultMap.put("cookies", cookies);
		    resultMap.put("message", "ajax请求,跨域传递cookie成功");
		    String result = JsonUtils.objectToJson(resultMap);
			response.getWriter().write(result);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

(2)前端页面代码如下:

注意:withCredentials和crossDomain(作用不明)

//4.ajax跨域携带cookie和自定义请求头header
         function getCookieAjaxCross() {
             $.ajax({
                 type:"get", 
                 url:"http://czt.ming.com/industry/api/publishForeign/getCookieAjax",
                 async:true,
                 data:{},
                 dataType: 'json',
                 xhrFields: {
                     withCredentials: true // 发送Ajax时,Request header中会带上 Cookie 信息。
                 },
                 crossDomain: true, // 发送Ajax时,Request header 中会包含跨域的额外信息,但不会含cookie(作用不明,不会影响请求头的携带)
                 success: function(data) {
                     console.log(data);
                 }
             });
         }
         getCookieAjaxCross();

(3)测试ajax跨域请求获取和创建cookie:
通过http://czt.casicloud.com/xxx/xxx访问页面,js触发ajax跨域请求http://czt.ming.com/xxx/xxx/xxxx/getCookieAjax,前端和后台如果不按照代码中配置相应参数会报各种跨域错误;

3. ajax跨域请求,携带请求头header案例(java)

(1)启动一个java web项目,配置两个域名(host),czt.ming.com、czt.casicloud.com;
(2)ajax跨域携带请求头会发送两次请求,一次预检查请求(options),预检查请求通过之后才会进行真正的请求,所以java后台需要配置相应的跨域过滤器,如下:

import java.io.IOException;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
 * 
    * @ClassName: CorsFilter
    * @Description: TODO(跨域请求过滤器)
    * @author clm
    * @date 2019年10月25日
    *
 */
public class CorsFilter implements Filter {
	@Override
	public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain)
			throws IOException, ServletException {
		/*
		 * 跨域请求头服务端配置:
		 * 1.Access-Control-Allow-Origin:设置允许跨域的配置, 响应头指定了该响应的资源是否被允许与给定的origin共享
		 * 2.Access-Control-Allow-Credentials:响应头表示是否可以将对请求的响应暴露给页面(cookie)。返回true则可以,其他值均不可以。
		 * 3.Access-Control-Allow-Headers:用于预检请求中,列出了将会在正式请求的 Access-Control-Request-Headers 字段中出现的首部信息。(自定义请求头)
		 * 4.Access-Control-Allow-Methods:在对 预检请求的应答中明确了客户端所要访问的资源允许使用的方法或方法列表。
		 */
		HttpServletRequest httpRequest = (HttpServletRequest) servletRequest;
		HttpServletResponse httpResponse = (HttpServletResponse) servletResponse;
		//设置允许多个域名允许跨域集合
        String[] allowDomains = {"http://czt.casicloud.com", "http://czt.ming.com"};
        Set<String> allowOrigins = new HashSet<String>(Arrays.asList(allowDomains));
        String origin = httpRequest.getHeader("Origin");
        if(allowOrigins.contains(origin)){
            //设置允许跨域的配置:Access-Control-Allow-Origin: 响应头指定了该响应的资源是否被允许与给定的origin共享
        	httpResponse.setHeader("Access-Control-Allow-Origin", origin);
        }
        httpResponse.setHeader("Access-Control-Allow-Credentials", "true");
		httpResponse.setHeader("Access-Control-Allow-Headers",
				"Origin, X-Requested-With, Content-Type, Accept, access-token");
		httpResponse.setHeader("Access-Control-Allow-Methods", "GET, PUT, DELETE, POST, OPTIONS");
		if (httpRequest.getMethod().equalsIgnoreCase("OPTIONS")) {
			httpResponse.setStatus(202);
			httpResponse.getWriter().close();
			return;
		}
		filterChain.doFilter(servletRequest, servletResponse);
	}
	@Override
	public void destroy() {
	}
	@Override
	public void init(FilterConfig filterConfig) throws ServletException {
	}
}
web.xml中配置过滤器:
	<filter>
		<filter-name>CorsFilter</filter-name>
		<filter-class>xxx.xxx.xxx.xx.xxx.CorsFilter</filter-class>
	</filter>
	<filter-mapping>
		<filter-name>CorsFilter</filter-name>
		<url-pattern>/*</url-pattern>
	</filter-mapping>

(3)java后台Controller代码:

/**
	 * 
	    * @Title: getPersonHeader
	    * @Description: TODO(跨域获取请求头)
	    * @param request
	    * @param response
	 */
	@RequestMapping(value ="/getPersonHeader",method=RequestMethod.GET)
	public void getPersonHeader(HttpServletRequest request, HttpServletResponse response){
	    try {
	    	response.setCharacterEncoding("UTF-8");
	    	String personHeader = request.getHeader("Access-Token");
	    	System.err.println("获取自定义请求头(Access-Token):" + personHeader);
		    //数据
		    Map<String, Object> resultMap = new HashMap<String, Object>();
		    resultMap.put("message", "跨域获取请求头成功");
		    resultMap.put("personHeader", personHeader);
		    String result = JsonUtils.objectToJson(resultMap);
			response.getWriter().write(result);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

(4)前端页面代码如下:

//同域前端设置自定义请求头,后端获取自定义请求头
         function getPersonHeader() {
             $.ajax({
                 type:"get", 
                 url:"/xxx/xxx/xxx/getPersonHeader",
                 async:true,
                 //ajax配置请求头方式,第一种
                 headers: {
                     "Access-Token":"Access-Token123456",//自定义请求头
                     "Content-Type":"application/json;charset=utf8"
                 },
                //ajax配置请求头方式,第二种
	            //beforeSend : function(request) {
	          //   request.setRequestHeader("Access-Token", "Access-Token123456");
	            //   request.setRequestHeader("Content-Type", "application/json;charset=utf8");
	            /