栏目分类:
子分类:
返回
终身学习网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
终身学习网 > IT > 软件开发 > 后端开发 > Java

CORS详解及处理方式

Java 更新时间:发布时间: 百科书网 趣学号
CORS详解及处理方式

参考:http://javascript.ruanyifeng.com/bom/cors.html

CORS(cross-origin resource sharing):跨源资源共享,允许浏览器对不同源的发出XMLHttpRequest请求,也就是克服ajax只能同源使用的限制。

现代浏览器会自动检测是否跨域,并自动完成一些操作。服务端同时对这种请求进行处理。所以需要浏览器端和服务端同时完成。

  • 自动添加一些头部信息
  • 或者多发一次请求

CORS分类

  • 简单请求

    • 请求方式为:HEAD、GET、POST

    • 请求头字段限制为以下(一些通用请求头不列出)

      Accept
      Accept-Lanuage
      Last-Event-ID
      Content-Typeapplication/x-www-form-urlencoded、multipart/form-data、text/plain
    • 注意这种方式是为了和表单请求相对应。表单请求就是简单请求,并且是可以跨源的。这样是为了避免开发者使用表单请求,而不是使用ajax。

  • 复杂请求

1 简单请求 1.1 流程 1 发送请求(请求格式)
GET /cros HTTP/1.1
Origin: http://api.bob.com
Host: api.bob.com
Accept-Language: zh-CN
Connection: alive
User-Agent: Mozilla/5.0

浏览器对于简单请求会发出一个带有Origin的请求信息,标注了这个请求来自的源。

2 服务器处理
  • 不进行处理,直接返回(是的,可以直接返回结果)。此时浏览器可以查看结果(但是不能处理),因为返回请求头没有Access-Control-Allow-Origin字段的话,会抛出一个异常,被XMLHttpRequest的onerror函数捕获。

  • 处理

    服务端添加返回header

    public Map first(HttpServletRequest request, HttpServletResponse response) {
        response.setHeader("Access-Control-Allow-Origin", "*");
        response.setHeader("Customize-Header", "xiao");
        HashMap hashMap = new HashMap();
        hashMap.put("name", "xiaojianbiao");
        return hashMap;
    }
    
  • 其他头部信息

是否必须作用
Access-Contorl-Allow-Origin*,Origin对应的值
Access-Control-Allow-Credentialstrue是否允许浏览器发送cookie
Access-Control-Expose-Headers字符串允许浏览器获取的额外的header字段(否则只能获取特定的header字段)
1.2 cookie处理

除了服务端允许发送cookie(主要是复杂请求,会有预检请求),浏览器端也要设置发送cookie(默认情况下是不发送的)

  • 设置withCredentials属性为true
var xHttp = new XMLHttpRequest();
xHttp.withCredentials = true;
  • cookie此时依旧遵循同源策略,就是不同源名下的cookie是不会发送到服务端的。也就是说虽然进行了跨源访问,但是cookie不会跨源,与服务端同源的cookie才会上传。
  • Access-Control-Allow-Credentials必须设置与Origin相同。
2 复杂请求

请求方式是DELETE、PUT,或Content-Type是application/json等格式。

2.1 流程 1 发送预检请求

请求代码

var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
    if (this.readyState == 4 && this.status == 200) {
        document.getElementById("demo").innerHTML =
            this.responseText;
    }
};
xhttp.open("PUT", "http://localhost:8089/demo/demo_get.asp", true);
xhttp.setRequestHeader("Content-Type", "application/json")
xhttp.send();

请求信息(预检)

OPTIONS /demo/demo_get.asp HTTP/1.1
Host: localhost:8089
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:92.0) Gecko/20100101 Firefox/92.0
Accept: */*
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
Access-Control-Request-Method: PUT
Access-Control-Request-Headers: content-type
Origin: https://www.w3school.com.cn

OPTIONS类型的请求,附带着将要进行CROS请求的方法类型(Access-Control-Request-Method),额外的请求header字段(Access-Control-Request-Headers)。

2 预检回应
HTTP/1.1 200 
Vary: Origin
Vary: Access-Control-Request-Method
Vary: Access-Control-Request-Headers
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET,HEAD,POST
Access-Control-Allow-Headers: content-type
Access-Control-Max-Age: 1800
Allow: GET, HEAD, POST, PUT, DELETE, OPTIONS, PATCH
  • Access-Control-Allow-Origin
    • 允许的请求源
  • Access-Control-Allow-Methods: GET,HEAD,POST
    • 允许跨源请求的方法
  • Access-Control-Allow-Headers: content-type
    • 浏览器支持的header字段
  • Access-Control-Max-Age: 1800
    • 本次跨源请求的有效期,在次有效期内不用再次预检。单位为秒。
  • Access-Control-Allow-Credentials
    • 含义同上
3 springboot中的跨域处理 3.1 手动添加代码处理

手动添加response的header的Access-Control-Allow-Origin字段。

@RequestMapping(value = "/demo/demo_get.asp")
public Map first(HttpServletRequest request, HttpServletResponse response) {
    response.addcookie(cookie);
    response.setHeader("Access-Control-Allow-Origin", "*");
    HashMap hashMap = new HashMap();
    hashMap.put("name", "xiaojianbiao");
    return hashMap;
}

注意:这种方式只能处理简单请求,如果是复杂请求的预检阶段会被拦截从而报403错误

3.2 注解

使用@CrossOrigin注解,这种方式可以解决复杂请求403错误问题

@CrossOrigin(origins = "*")
@RequestMapping(value = "/demo/demo_get.asp")
public Map first(HttpServletRequest request, HttpServletResponse response) {
    HashMap hashMap = new HashMap();
    hashMap.put("name", "xiaojianbiao");
    return hashMap;
}
转载请注明:文章转载自 www.051e.com
本文地址:http://www.051e.com/it/282132.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 ©2023-2025 051e.com

ICP备案号:京ICP备12030808号