前言

  • 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很贴心的提供了不同粒度的控制。这里介绍全局设置。

  1. 添加注解@CrossOrigin
@CrossOrigin(origins = {"*"})
@SpringBootApplication
public class Application {
...
}

说明:origins 不建议使用*(为了方便这里用*。实际应用时,老老实实的一个一个的添加)。

  1. 或者 addCorsMappings
@Configuration
public class WebConfig implements WebMvcConfigurer {

	@Override
	public void addCorsMappings(CorsRegistry registry) {
		registry.addMapping("/api/**");
	}
	
}
  1. 测试
    测试略。模拟跨域请求,可以在浏览器里发送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 补充

  1. SpringBoot注解@CrossOrigin不起作用
  2. addCorsMappings 方式依然有效。
@Configuration
public class WebConfig implements WebMvcConfigurer {

	@Override
	public void addCorsMappings(CorsRegistry registry) {
		registry.addMapping("/api/**");
	}
	
}

想了解更多,参考这里

参考

https://zhuanlan.zhihu.com/p/38972475