前言
- springboot 2.1.1.RELEASE
- 360极速浏览器 12.0.1476.0 (正式版本) (32 位)
- jquery 3.5.0
- 接口跨域请求有两者方式:
- jsonp
- CORS
JSONP
JSONP(JSON with Padding)是利用浏览器对script的资源引用没有同源限制,通过动态插入一个script标签,当资源加载到页面后会立即执行的原理实现跨域的。
JSONP是一种非正式传输协议,具体做法是:用户传递一个callback参数给服务端。服务端返回数据时用callback参数包裹住JSON数据,形如callback({name:'zhangsan',age:18})
。
JSONP只支持GET请求(不支持POST等其它类型的HTTP请求),它只支持跨域HTTP请求这种情况,不能解决不同域的两个页面之间如何进行JavaScript调用的问题。
JSONP的优势在于支持老式浏览器,弊端也比较明显:需要客户端和服务端定制进行开发。
CORS
Cross-Origin Resource Sharing (CORS) 是W3c工作草案,它定义了在跨域访问资源时浏览器和服务器之间如何通信。CORS背后的基本思想是使用自定义的HTTP头部允许浏览器和服务器相互了解对方,从而决定请求或响应成功与否。
CORS的具体做法为:浏览器发现请求不符合同源策略时,给请求加一个请求头Origin
。服务端如果接受请求则在返回结果中加入一个响应头Access-Control-Allow-Origin
。
CORS与JSONP的使用目的相同,但是比JSONP更强大。CORS支持所有的浏览器请求类型,承载的请求数据量更大(因为URL是有长度限制的,参考这里。以目前的技术看,URL没有长度限制,那是不可想象的)。
CORS也不是万能的,老旧的浏览器就不支持。
CORS请求分成两类:简单请求(simple request)和非简单请求(not-so-simple request)。下面的方法只在简单请求下做了测试。
springboot 启用 @CrossOrigin
springboot很贴心的提供了不同粒度的控制。这里介绍全局设置。
- 添加注解
@CrossOrigin
@CrossOrigin(origins = {"*"})
@SpringBootApplication
public class Application {
...
}
说明:origins 不建议使用*
(为了方便这里用*
。实际应用时,老老实实的一个一个的添加)。
- 或者
addCorsMappings
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/api/**");
}
}
- 测试
测试略。模拟跨域请求,可以在浏览器里发送ajax请求,参考这里(使用jquery调试ajax接口-2)。
Http 请求如下(http://localhost:8085/api/sample/form/get1):
GET /api/sample/form/get1 HTTP/1.1
Host: localhost:8085
Connection: keep-alive
Accept: */*
Origin: null
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36
Sec-Fetch-Site: cross-site
Sec-Fetch-Mode: cors
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9
Http 响应如下:
HTTP/1.1 200
Vary: Origin
Vary: Access-Control-Request-Method
Vary: Access-Control-Request-Headers
Access-Control-Allow-Origin: *
Content-Type: application/json;charset=UTF-8
Transfer-Encoding: chunked
Date: Fri, 04 Sep 2020 06:09:46 GMT
springboot 2.2.13.RELEASE 补充
- SpringBoot注解@CrossOrigin不起作用
addCorsMappings
方式依然有效。
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/api/**");
}
}
想了解更多,参考这里。
参考
https://zhuanlan.zhihu.com/p/38972475