ajax跨域的非简单请求,ajax跨域问题------非简单请求

如果是非简单请求, 浏览器就不会真的马上去发这个请求, 会先发预检命令 (发试探的请求)

fd2cb698f8d2?utm_campaign=maleskine&utm_content=note&utm_medium=seo_notes&utm_source=recommendation

7.png

发送json的ajax请求

$.ajax({

type : "post",

url: "http://localhost:8080/test/postJson",

//这样传json是属于非简单请求 会先预检

contentType : "application/json;charset=utf-8",

data: JSON.stringify({name: "xiaofengqing"}),

success: function(json){

result = json;

}

});

后端代码

@PostMapping("/postJson")

public ResultBean postJson(@RequestBody User user) {

System.out.println("TestController.postJson()");

return new ResultBean("postJson " + user.getName());

}

对应这样的非简单请求,浏览器的会先发这样一条预检命令

fd2cb698f8d2?utm_campaign=maleskine&utm_content=note&utm_medium=seo_notes&utm_source=recommendation

预检命令.png

fd2cb698f8d2?utm_campaign=maleskine&utm_content=note&utm_medium=seo_notes&utm_source=recommendation

要求同意头.png

但是如图↑后端返回的响应头里面,没有写明同意这个 content-type

浏览器看到后, 就知道预检不通过了 报错

fd2cb698f8d2?utm_campaign=maleskine&utm_content=note&utm_medium=seo_notes&utm_source=recommendation

浏览器报错.png

之后就不会真的去发生这个非简单请求,

后端那个controller根本没进去

在过滤器里面 加这么一句,特地去加预检命令要求的这个头

res.addHeader("Access-Control-Allow-Headers", "Content-Type");//允许非简单 就是往这里传json

试一试:

fd2cb698f8d2?utm_campaign=maleskine&utm_content=note&utm_medium=seo_notes&utm_source=recommendation

对预检命令的响应头变了.png

fd2cb698f8d2?utm_campaign=maleskine&utm_content=note&utm_medium=seo_notes&utm_source=recommendation

通过.png

这样就能通过

浏览器发预检命令 请求头里面说 需要响应头里面同意Content-Type

Access-Control-Request-Headers: content-type

响应头里面有 同意头Content-Type

Access-Control-Allow-Headers: Content-Type 预检命令成功,

就会真的去补发我们要的那个非简单请求

带自定义头

再来一个 带自定义头的请求(明显也是非简单请求)

$.ajax({

type : "get",

url: "http://localhost:8080/test/getHeader",

//加头的方法1

headers:{

"x-header1" : "AAA"

},

//加头的方法2

beforeSend: function(xhr){

xhr.setRequestHeader("x-header2","BBB")

},

success: function(json){

result = json;

}

});

服务端

@GetMapping("/getHeader")

public ResultBean getHeader(

@RequestHeader("x-header1") String header1,

@RequestHeader("x-header2") String header2) {

System.out.println("TestController.getHeader()");

return new ResultBean("getHeader " + header1 + " " + header2);

}

浏览器控制台报错

:8081/#:1 Failed to load http://localhost:8080/test/getHeader: Request header field x-header2 is not allowed by Access-Control-Allow-Headers in preflight response.

确实 浏览器发出的请求头里面有写这个要求

Access-Control-Request-Headers: x-header1,x-header2

而相应头里面 没有满足这个要求

最终版

请求头里面要求响应头里面写支持什么头 都一律支持

String headers = req.getHeader("Access-Control-Request-Headers");

if (!org.springframework.util.StringUtils.isEmpty(headers)) {

res.addHeader("Access-Control-Allow-Headers", headers);

}

res.addHeader("Access-Control-Max-Age", "3600");//options预检命令缓存 这个时间段

缓存

每次非简单请求 都向服务端发2次请求 太没效率了

服务端 还可以让浏览器缓存预检命令结果,

再发非简单请求 不用再给服务端发预检命令了,可以直接看浏览器直接的缓存

res.addHeader("Access-Control-Max-Age", "3600");//单位是秒

//options预检命令缓存 这个时间段:1小时

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值