Springboot后台设置允许跨域的方法
1、在启动类中继承WebMvcConfigurerAdapter,重写其中的addCorsMappings方法package com.example.springbootdemo;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootAppl
1、在启动类中继承WebMvcConfigurerAdapter,重写其中的addCorsMappings方法
package com.example.springbootdemo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
@SpringBootApplication
public class SpringbootdemoApplication extends WebMvcConfigurerAdapter {
public static void main(String[] args) {
SpringApplication.run(SpringbootdemoApplication.class, args);
}
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowCredentials(true)
.allowedHeaders("*")
.allowedOrigins("*")
.allowedMethods("*");
}
}
2、在允许跨域请求的controller中使用@CrossOrigin 注解
import org.springframework.web.bind.annotation.CrossOrigin;
@CrossOrigin
@RestController
public class HelloWorldController {
/**
*
*
*/
}
Access-Control-Allow-Origin
response.setHeader("Access-Control-Allow-Origin", "*"); //设置允许任何域名跨域访问
response.setHeader("Access-Control-Allow-Origin", "http://localhost:8080/");//设置指定域访问
Access-Control-Allow-Credentials
Access-Control-Allow-Credentials 这个是服务端下发到客户端的 response 中头部字段,意义是允许客户端携带验证信息,例如 cookie 之类的,我们的客户端和服务端交互的时候使用的是 token,通过 Authorization头发送到服务端
Access-Control-Allow-Headers
当浏览器发送接口请求出现跨域问题时,目前的做法通常会在接口服务器增加如下配置。
Access-Control-Allow-Origin: *
复制代码
但是有时也会出现 Access-Control-Allow-Headers
的错误问题。
Access to XMLHttpRequest at 'http://www.xxx.com/api' from origin 'http://localhost:8080' has been blocked by CORS policy: Request header field content-type is not allowed by Access-Control-Allow-Headers in preflight response.
复制代码
下面我们就来分析一下原因和解决办法。
原因
浏览器在发送跨域请求并且包含自定义 header 字段时,浏览器会先向服务器发送 OPTIONS 预检请求(preflight request),探测该请求服务是否允许自定义跨域字段。
如果允许,则继续执行 POST、GET请求,否则返回提示错误。
OPTIONS 请求:
Request URL:http://xxx.com/api
Request Method:OPTIONS
Status Code:200 OK
Remote Address:00.00.00.00:80
Referrer Policy:no-referrer-when-downgrade
复制代码
Request Header:
Accept:*/*
Accept-Encoding:gzip, deflate
Accept-Language:zh-CN,zh;q=0.9,en;q=0.8
Access-Control-Request-Headers:content-type,xfilecategory,xfilename,xfilesize
Access-Control-Request-Method:GET
Connection:keep-alive
Host:http://localhost:8080/
Origin:http://localhost:8080/
User-Agent:Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit/604.1.38 (KHTML, like Gecko) Version/11.0 Mobile/15A372 Safari/604.1
复制代码
注意⚠️
此时浏览器会向服务器发送预检请求,询问是否支持跨域的自定义 header 字段。设置的 Access-Control-Request-Headers
服务器需要适当的作出应答。
服务器应答方式
服务器需要对 OPTIONS 请求作出应答,通过设置 header 包含 Access-Control-Request-Headers
,并且包含 OPTIONS 请求中的 Access-Control-Request-Headers
对值。
例如:
response.setHeader("Access-Control-Allow-Headers", "Content-Type,Access-Token");
复制代码
另外(其实很重要)
如果你对请求是 simple headers 方式则不会发送预检请求。
- Accept
- Accept-Language
- Content-Language
- Content-Type
当仅包含以上这些请求头(以及满足下面列出的附加要求的值)时,请求不需要在 CORS 的上下文中发送预检请求。
附加要求
CORS 安全标头还必须满足以下要求才能成为 CORS 安全的请求标头:
- 对于
Accept-Language
和Content-Language
:只能存在值0-9
,A-Z
,a-z
,空间或*,=.;=
。 - 关于
Accept
和Content-Type
:不能包含 CORS 不安全的请求头字节:"():<>?@[\]{}
,Delete
,Tab
和控制字符:0x00
到0x19
。 Content-Type
:需要有一个 MIME 类型的值(忽略参数)。可以是application/x-www-form-urlencoded
、multipart/form-data
或text/plain
的任意一个。- 对于任何
header
:值的长度不能大于 128。
通常影响程序发送预检请求的总是 Content-Type
的设置。如果我们在跨域请求时不需要发送预检请求,那么可以通过设置浏览器请求 Content-Type
为 application/x-www-form-urlencoded
、multipart/form-data
或 text/plain
的任意一个来避免。
例如:
headers.set('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8');
Access-Control-Allow-Methods
Access-Control-Request-Method
是浏览器在CORS预检请求中设置的请求标头,它只能有一个值.所述Access-Control-Allow-Methods
报头是CORS响应报头,并且它可以具有多个值.我假设你问的是Access-Control-Allow-Methods
因为这是服务器指定的值.
的Access-Control-Allow-Methods
报头指示该HTTP方法允许对跨域请求特定端点.如果您允许所有HTTP方法,那么可以将值设置为类似的值Access-Control-Allow-Methods: GET, PUT, POST, DELETE, HEAD
.但是,如果要将端点限制为仅限几种方法,则应仅包括这些方法.
更多推荐
所有评论(0)