ajax请求携带自定义请求头header(跨域和同域)
创始人
2025-05-28 07:17:07

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 resultMap = new HashMap();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);}//获取cookieCookie[] cookies = request.getCookies();//设置cookieCookie cookie = new Cookie("access_token_ajax", UUID.randomUUID().toString());cookie.setPath("/");response.addCookie(cookie);//数据Map resultMap = new HashMap();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和自定义请求头headerfunction 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 {@Overridepublic 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 allowOrigins = new HashSet(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);}@Overridepublic void destroy() {}@Overridepublic void init(FilterConfig filterConfig) throws ServletException {}}
web.xml中配置过滤器:CorsFilterxxx.xxx.xxx.xx.xxx.CorsFilterCorsFilter/*
(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 resultMap = new HashMap();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");//}data:{},success: function(data) {console.log(data);}});}getPersonHeader();//跨域前端设置自定义请求头,后端获取自定义请求头function getPersonHeaderCross() {$.ajax({type:"get", url:"http://czt.ming.com/xxx/xxx/xxx/getPersonHeader",async:true,headers: {"Access-Token":"Access-Token123456",//自定义请求头"Content-Type":"application/json;charset=utf8"},data:{},crossDomain: true, // 发送Ajax时,Request header 中会包含跨域的额外信息,但不会含cookie(作用不明,不会影响请求头的携带)success: function(data) {console.log(data);}});}getPersonHeaderCross();

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

3. jsonp实现跨域读写cookie案例(java)

(1)启动一个java web项目,配置两个域名(host),czt.ming.com、czt.casicloud.com;

(2)java后台jsonp代码:
	/*** * @Title: setCookie* @Description: TODO(jsonp跨域设置cookie)* @param request* @param response*/@RequestMapping(value ="/setCookie.jsonp",method=RequestMethod.GET)public void setCookie(HttpServletRequest request, HttpServletResponse response){try {response.setCharacterEncoding("UTF-8");//设置cookieCookie cookie = new Cookie("access_token", UUID.randomUUID().toString());cookie.setPath("/");response.addCookie(cookie);//数据Map resultMap = new HashMap();resultMap.put("cookie", cookie);resultMap.put("message", "跨域设置cookie成功");String result = JsonUtils.objectToJson(resultMap);//前端传过来的回调函数名称String callback = request.getParameter("callback");//用回调函数名称包裹返回数据,这样,返回数据就作为回调函数的参数传回去了result = callback + "(" + result + ")";response.getWriter().write(result);} catch (Exception e) {e.printStackTrace();}}/*** * @Title: getCookie* @Description: TODO(jsonp跨域获取cookie)* @param request* @param response*/@RequestMapping(value ="/getCookie.jsonp",method=RequestMethod.GET)public void getCookie(HttpServletRequest request, HttpServletResponse response){try {response.setCharacterEncoding("UTF-8");//获取cookieCookie[] cookies = request.getCookies();//数据Map resultMap = new HashMap();resultMap.put("cookies", cookies);resultMap.put("message", "跨域获取cookie成功");String result = JsonUtils.objectToJson(resultMap);//前端传过来的回调函数名称String callback = request.getParameter("callback");//用回调函数名称包裹返回数据,这样,返回数据就作为回调函数的参数传回去了result = callback + "(" + result + ")";response.getWriter().write(result);} catch (Exception e) {e.printStackTrace();}}
(3)前端代码:
 		 //1.jsonp跨域设置cookiefunction setCookieCrossJsonp() {$.ajax({type:"get", url:"http://czt.ming.com/industry/api/publishForeign/setCookie.jsonp",async:true,data:{},dataType: "jsonp",  //返回类型为jsonp,实现跨域jsonp:"callback",   //jsonp和jsonpCallBack相当于在url后添加一个参数:?callback=backjsonpCallback:"back",   //设定回调函数的名字,传到后台,进行包装,不设定自动生成success: function(data) {   //成功执行处理,对应后台返回的back(data)方法console.log(data);}});}setCookieCrossJsonp();//2.jsonp跨域获取cookiefunction getCookieCrossJsonp() {$.ajax({type:"get", url:"http://czt.ming.com/industry/api/publishForeign/getCookie.jsonp",async:true,data:{},dataType: "jsonp",  //返回类型为jsonp,实现跨域jsonp:"callback",   //jsonp和jsonpCallBack相当于在url后添加一个参数:?callback=backjsonpCallback:"back1",   //设定回调函数的名字,传到后台,进行包装,不设定自动生成success: function(data) {   //成功执行处理,对应后台返回的back(data)方法console.log(data);}});}getCookieCrossJsonp();

(4)测试jsonp跨域请求获取和创建cookie:
通过http://czt.casicloud.com/xxx/xxx访问页面,js触发jsonp跨域请求http://czt.ming.com/xxx/xxx/xxxx/getCookie.jsonp、http://czt.ming.com/xxx/xxx/xxxx/setCookie.jsonp,能够正常跨域设置cookie和获取cookie;

ajax请求携带cookie、自定义header总结:

错误:

1.ajax请求时是不会自动带上cookie的,要是想让他带上的话,必须设置withCredential为true。

正确:
  1. ajax同域请求下,ajax会自动带上同源的cookie;

  2. ajax同域请求下,ajax添加自定义请求头(或原装)header,前端、后台不需要增加任何配置,
    并且不会因为增加自定义请求头header,而引起预检查请求(options);

  3. ajax跨域请求下,如果不需要携带cookie、请求头header,只需要在后台配置相应参数即可;
    后台参数:
    (1).Access-Control-Allow-Origin:设置允许跨域的配置, 响应头指定了该响应的资源是否被允许与给定的origin共享;

  4. ajax跨域请求下,ajax不会自动携带同源的cookie,需要通过前端配置相应参数才可以跨域携带同源cookie,后台配置相应参数才可以跨域返回同源cookie;
    前端参数:
    withCredentials: true(发送Ajax时,Request header中会带上Cookie信息)
    后台参数:
    (1).Access-Control-Allow-Origin:设置允许跨域的配置, 响应头指定了该响应的资源是否被允许与给定的origin共享;
    特别说明:配置了Access-Control-Allow-Credentials:true则不能把Access-Control-Allow-Origin设置为通配符*;
    (2).Access-Control-Allow-Credentials:响应头表示是否可以将对请求的响应暴露给页面(cookie)。返回true则可以,其他值均不可以。

  5. ajax请求任何时候都不会带上不同源的cookie(Cookie遵循同源策略);

  6. ajax跨域请求下,ajax添加自定义或者原装的请求头,请求会发送两次,第一次预检查请求,第二次正常请求,详细描述:
    post(或GET)跨域请求时,分为简单请求和复杂请求,跨域携带自定义或者原装请求头头时是复杂请求。
    复杂请求会先发送一个method 为option的请求,目的是试探服务器是否接受发起的请求. 如果服务器说可以,再进行post(或GET)请求。
    对于java后台web应用,跨域需要添加一个过滤器(过滤器详见下面案例代码),这个过滤器做的事就是,加了几个http header在返回中,
    Access-Control-Allow-Origin 我能接受的跨域请求来源,配置主机名
    Access-Control-Allow-Headers 表示能接受的http头部,别忘了加入你自己发明创造的头部
    Access-Control-Allow-Methods 表示能接受的http mothed ,反正就那几种,全写上也无妨,猥琐点就只写 post, options
    如果是OPTION返回空,设置返回码为202,202表示通过。
    需要前端配置相应参数才可以跨域携带请求头,后台配置相应参数进行跨域携带请求头;
    前端参数:
    crossDomain:true(发送Ajax时,Request header 中会包含跨域的额外信息,但不会含cookie(作用不明,不会影响请求头的携带))
    后台参数(配置预检查过滤器):
    (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:在对预检请求的应答中明确了客户端所要访问的资源允许使用的方法或方法列表;

亲测小结论:

1.ajax跨域请求下,后台不配置跨域Access-Control-Allow-Origin,同样能够执行后台方法,但是无法执行ajax的success的方法,控制台报跨域错误;
2.ajax跨域请求下,前端配置withCredentials: false,同样能够执行后台方法,但是无法携带同源cookie,后台无法获取;
3.ajax跨域请求下,前端配置withCredentials: true,后端没有配置Access-Control-Allow-Credentials:true,同样能够执行后台方法,并能够生成cookie并返回浏览器,但是无法执行ajax的success的方法,控制台报跨域错误;
4.ajax跨域请求下,前端配置withCredentials: false或不配置withCredentials,后端配置Access-Control-Allow-Credentials:true或者false,同样能够执行后台方法,并能够生成cookie并返回浏览器,但是无法携带同源cookie,能够执行ajax的success的方法;
5.Cookie携带只区分域名,不区分端口;
6.jsonp可以携带cookie,但只能携带所属域名的cookie(同源策略);
7.jsonp可以跨域生成cookie,流程如下:跨域请求之后,在服务器端生成cookie,并在浏览器端记录相应的cookie;
8.静态资源同样会携带cookie(js和图片等),但是如果是和当前页面不同域只是在network中不显示cookie选项,但是后台能够获取到对应cookie;
9.ajax同域请求会自动带上同源的cookie,不会带上不同源的cookie;
10.这是MDN对withCredentials的解释: MDN-withCredentials ,我接着解释一下同源。
众所周知,ajax请求是有同源策略的,虽然可以应用CORS等手段来实现跨域,但是这并不是说这样就是“同源”了。ajax在请求时就会因为这个同源的问题而决定是否带上cookie,这样解释应该没有问题了吧,还不知道同源策略的,应该去谷歌一下看看。

总结:最好前端后台配置跨域,则同时配置相应的跨域配置,否则总会出现不可控的错误;

参考博客:
1.ajax如何带上cookie:
2.跨域请求设置withCredentials(转):
3.Ajax 带请求头header的get、post请求在原生JS中应用讲解:
4.ajax请求携带 cookie:
5.ajax跨域 自定义header:
6.ajax 自定义header跨域时, option的处理:
7.JQuery.Ajax + 跨域 (crossDomain) + POST + JSON + WCF RESTful, 5大陷阱和解决方案:
8.跨域请求及跨域携带Cookie解决方案:
9.Access-Control-Allow-Methods:
10.Access-Control-Allow-Origin:
11.Access-Control-Allow-Credentials:
12.ajax请求中自定义添加请求头:
13.jsonp cookie 跨域原理详解:
14.jsonp实现跨域读写cookie:

相关内容

热门资讯

【Java闭关修炼】Sprin... # 配置Mysql与注册登录模块应用服务模型IDEA 连接数据库点击IDEA右侧的database ...
Oracle 常见报错问题汇总 Oracle 常见报错问题汇总 报错:ORA-01017: invalid username/pas...
计算不规则区域的周长和面积——... 1.题目描述 设计求不规则区域周长和面积计算的算法。 测试数据的获得: 输入样例&#x...
STM32之IIC IIC协议IIC全称Inter-Integrated Circuit (集成电路总线),...
Vue3 使用MD5加密(清晰... 概述 最近在想做个cloud项目,gitee上找了个模板项目,前端使用到vue3 &#...
使用Idea编译Nacos源码... 其实nacos下载下来启动就可以了,但是为了方便一些,而且Nacos在GitHub上下载是真的慢,可...
【abp Vnext】下载并运... 软件环境:电脑需要基础软件环境node.js、npm,这些网上教程很多&...
一文了解|氢燃料电池行业痛点问... 早在1839年的英国,一位名叫威廉格罗夫的科学家,就已发明了一款通过氢气...
华秋工艺分享:第八道主流程之丝... 如图,第八道主流程为 文字 。 文字的目的:文字又名字符。是线路板上白色...
Redis10大数据类型 Redis10大数据类型Redis键(key)一、Redis字符串&#x...
MySQL变量的使用 文章目录1、系统变量1.1 查看系统变量1.2 设置系统变量2、用户变量2.1 定义用户变量2.2 ...
IntelliJ IDEA创建... 目录 ——————————————————————————————— 一、创建Java项目 1、创建...
Qt学习_08_用独立的文件存... 0 前言 上一篇笔记对样式表进行了初步学习,QT学习_07_样式表的初步学习_江湖上都...
小黑子—多媒体技术与运用基础知... 多媒体技术与运用1.0多媒体系列第一章1. 计算机媒体概述1.1 媒体的分类1.2 小结2. 多媒体...
自主移动机器人AMR控制器设计... 近年来,随着社会和技术发展,自主移动已经成为了仓储物流[1]、无人驾驶[...
Java Web应用开发——第... 第二章:JSP基本语法测验 一.单项选择题(共15题,49.5分...
代码自动生成工具实战-Curs... 文章目录Cursor code generate介绍Cursor 代码生成实战prompt1prom...
普通Java工程师 VS 优秀... 1 核心能力 1.1 要成为一名优秀的Java架构师 只懂技术还远远不够,懂技术/懂业...
【爬虫】一、前置知识 一、Web请求过程解析 1.服务器渲染:在服务器端把数据和html整合在一起ÿ...
文心一言话题的思考 ⭐️我叫忆_恒心,一名喜欢书写博客的在读研究生👨‍🎓。...
react-native an... 1. 配置环境 必须安装的依赖有:Node、JDK 和 Android Studio。...
若依分离版选择弹窗数据回读 最近学习若依框架过程中想要实现点击按钮显示弹窗,在弹窗选择信息后回读到父组件中显示&#...
板边器件距离不够,导致元器件无... 电子元器件在PCB板上的 合理布局 ,是减少焊接缺点的极重要一环!元器件...
sdbusplus:通过con... sdbusplus:通过new_method_call同步调用service的meth...
骷髅病毒分析 一、病毒信息病毒名称:骷髅病毒文件名称:d5dac2456fa67584...
使用CRT调式库调式运行时堆 #include#include#define CRTDBG_MAP_ALLOC#include #...
Hive的UDF实现两种简单方... Hive的UDF实现两种简单方法+通过编译源码添加UDF 一、实现简单的say_hello ...
211本科生就业难,绝不是个例... 曾几何时,我们在高中时期日以继夜地努力学习,只为在高考中获得更高的分数&...
Java【多线程基础2】 Th... 文章目录前言一、Thread类1, 构造方法2, 常用成员属性3, 常用成员方法3.1, start...
MySQL分区 一张表的数据在物理层面都是存放在一起的。随着业务增长,当一张表的数据量过大时ÿ...