리소스가 리소스 자체가 있는 서버가 아닌 다른 도메인이나 포트에서 리소스를 요청하면 리소스는 교차 도메인 HTTP 요청을 시작합니다. .
보안상의 이유로 브라우저는 스크립트 내에서 시작된 교차 출처 HTTP 요청을 제한합니다. 예를 들어 XMLHttpRequest와 Fetch API는 동일한 원본 정책을 따릅니다. 이는 CORS 헤더가 사용되지 않는 한 이러한 API를 사용하는 웹 애플리케이션은 애플리케이션이 로드된 동일한 도메인에서만 HTTP 리소스를 요청할 수 있음을 의미합니다.
프런트 엔드에 "Access-Control-Allow-Origin" 문제가 표시되는 경우
XMLHttpRequest는 http://xxxxxxxxxx/를 로드할 수 없습니다. 'Access-Control-Allow-Origin' 헤더가 없습니다. 요청된 리소스이므로 원본 'null'은 액세스가 허용되지 않습니다.
그런 다음 교차 도메인 액세스를 허용하려면 SpringBoot2에서 교차 도메인 필터를 구성해야 합니다.
import java.io.IOException; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.springframework.stereotype.Component; @Component public class CorsFilter implements Filter { @Override public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException { HttpServletRequest request = (HttpServletRequest) req; HttpServletResponse response = (HttpServletResponse) res; response.setHeader("Access-Control-Allow-Origin", "*"); response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE, PUT, GET"); response.setHeader("Access-Control-Max-Age", "3600"); response.setHeader("Access-Control-Allow-Headers", "x-requested-with"); chain.doFilter(req, res); } @Override public void init(FilterConfig filterConfig) {} @Override public void destroy() {} }
크로스 도메인 주소 표시가 필요한 경우 문제 해결을 위해 액세스 소스 인쇄문을 추가할 수도 있습니다
String curOrigin = request.getHeader("Origin"); System.out.println("###跨域过滤器->当前访问来源->"+curOrigin+"###");
크로스 도메인 권한이 필요한 경우 소스를 확인할 수 있습니다
String curOrigin = request.getHeader("Origin"); System.out.println("###跨域过滤器->当前访问来源->"+curOrigin+"###"); if(curOrigin.indexOf("127.0.0.1:8080")>-1){ response.setHeader("Access-Control-Allow-Origin", "*"); }
요청 URL의 프로토콜, 도메인 이름, 포트가 다른 경우 크로스 도메인입니다. 브라우저의 동일 출처 정책의 제한으로 인해 도메인 간 문제가 발생합니다.
동일 출처: 요청 URL의 프로토콜, 도메인 이름, 포트가 동일합니다. 이는 동일한 출처(동일 도메인)임을 의미합니다.
동일 출처 정책: 동일 출처 정책(Same Origin Policy)은 브라우저의 핵심이자 가장 기본적인 보안 기능입니다. 동일 출처 정책은 원본이 아닌 출처(동일 도메인)의 콘텐츠가 상호 작용하는 것을 방지합니다.
동일 출처 정책 제한:
원본이 아닌 웹페이지의 쿠키, LocalStorage 및 IndexedDB를 읽을 수 없습니다.
원본이 아닌 웹페이지의 DOM에 액세스할 수 없습니다
Un 읽을 수 있다 원본이 아닌 웹페이지 AJAX 요청을 보낼 주소
브라우저의 동일 출처 정책은 일반적으로 도메인 간 요청을 제한하는 두 가지 방법이 있습니다.
브라우저는 도메인 간 요청을 제한합니다.
Cross-domain 요청이 가능합니다. 정상적으로 시작되었으나, 반환된 결과가 브라우저에 의해 가로채어졌습니다.
일반적으로 브라우저는 두 번째 방식으로 도메인 간 요청을 제한합니다. 즉, 요청이 서버에 도달하여 데이터베이스의 데이터에 대해 작동했을 수 있지만 반환된 결과가 브라우저에 의해 차단되었습니다. 반환 결과를 얻을 수 없습니다. 이는 실패한 요청이지만 데이터베이스의 데이터에 영향을 미칠 수 있습니다.
이런 일이 발생하는 것을 방지하기 위해 사양에서는 서버 데이터에 부작용이 있을 수 있는 이 HTTP 요청 방법에 대해 브라우저가 먼저 OPTIONS 방법을 사용하여 실행 전 요청을 시작하여 서버가 교차를 허용하는지 확인하도록 요구합니다. 도메인 요청: 허용되면 데이터가 포함된 실제 요청이 전송됩니다. 그렇지 않으면 데이터가 포함된 실제 요청이 전송되지 않습니다.
원본이 아닌 콘텐츠가 상호 작용할 수 없는 문제를 해결하기 위한 현재 주류 솔루션은 CORS(교차 도메인 리소스 공유)입니다.
CORS(Cross-Origin Resource Sharing)는 브라우저의 요청이 동일한 소스에서 오는 경우에만 서버에서 데이터를 얻을 수 있다는 제한을 극복합니다.
CORS는 서버와 브라우저가 HTTP 프로토콜 위에 추가 HTTP 헤더 정보를 통해 도메인 간 리소스 공유를 협상한다는 데 동의합니다. 서버 측과 브라우저 모두 사양의 요구 사항을 준수해야 합니다.
CORS는 HTTP 교차 도메인 요청을 단순 요청과 비단순 요청의 두 가지 범주로 나눕니다. 다양한 요청은 다양한 정책에 따라 도메인 간 리소스 공유를 협상합니다.
간단한 도메인 간 요청에 충족해야 하는 조건:
1. 요청 방법은 GET, HEAD 또는 POST입니다(POST의 경우 Content-Type 값은 application/x-여야 함). www-form-urlencoded, multipart/form-data, text/plain의 값)
2. 요청에 사용자 정의 HTTP 요청 헤더가 없습니다.
HTTP 헤더에는 다음 필드만 포함될 수 있습니다.
Accept
Accept
Accept-Language
Content-Language
DPR
Downlink
Save-Data
Viewport-Width
Width
Content-Type
Accept-Language
Content-Language
DPR
다운링크
🎜🎜🎜🎜데이터 저장
🎜🎜🎜🎜뷰포트 너비🎜🎜🎜🎜<code>Width
🎜🎜🎜🎜Content-Type
🎜🎜🎜🎜🎜위의 두 가지 사항이 충족되면 간단한 도메인 간 요청입니다. . 🎜🎜🎜간단한 도메인 간 요청의 경우 처리 방법은 다음과 같습니다. 🎜🎜1. 브라우저가 해야 할 일은 HTTP 요청 헤더에 Origin을 추가하고 JavaScript 스크립트가 있는 도메인을 입력한 후 리소스를 요청하는 것뿐입니다. 다른 도메인의 서버에서. 🎜Origin: http://www.joker.com🎜원본 필드는 이 요청이 어느 소스에서 왔는지 나타내는 데 사용됩니다(프로토콜 + 도메인 이름 + 포트). 서버는 이 값을 기반으로 요청에 대한 동의 여부를 결정합니다. 🎜🎜2. 서버는 간단한 도메인 간 요청을 받은 후 리소스 권한 구성에 따라 응답 헤더에 Access-Control-Allow-Origin을 추가합니다. 🎜
如果Origin指定的源,不在许可范围内,服务器会返回一个正常的HTTP回应。 但这个响应头信息没有包含Access-Control-Allow-Origin字段,浏览器就知道该域名不在许可范围内。
如果Origin指定的域名在许可范围内,服务器返回的响应,会多出几个头信息字段:
Access-Control-Allow-Origin: http://www.joker.com Access-Control-Allow-Credentials: true Access-Control-Expose-Headers: My-Token
Access-Control-Allow-Origin
:该字段是必须的。它的值要么是请求时Origin字段的值,要么是一个*值,表示接受任意域名的请求。
Access-Control-Allow-Credentials
: 该字段是可选的。它的值是一个布尔值,表示是否允许发送Cookie。默认情况下,Cookie不包括在CORS请求之中。设为true,即表示服务器明确许可,Cookie可以包含在请求中,一起发给服务器。这个值也只能设为true,如果服务器不要浏览器发送Cookie,删除该字段即可。
Access-Control-Expose-Headers
:该字段是可选的。CORS请求时,XMLHttpRequest对象的getResponseHeader()方法只能拿到6个基本字段:Cache-Control、Content-Language、Content-Type、Expires、Last-Modified、Pragma。如果想拿到其他字段,就必须在Access-Control-Expose-Headers里面指定。
3.浏览器收到响应后,通过获取响应头中的Access-Control-Allow-Origin字段,来判断如果当前域已经得到授权,则将结果返回给JavaScript。否则浏览器忽略此次响应。
非简单跨域请求需满足的条件:
除GET、HEAD和POST(Content-Type的值是:application/x-www-form-urlencoded、multipart/form-data、text/plain中的一个值)以外的其他HTTP方法
如:PUT、DELETE、TRACE、PATCH、POST(Content-Type的值是:application/json)。
请求中有自定义HTTP头部。
以上两点只要至少满足其中一点就是非简单跨域请求。
对于非简单跨域请求,处理方式如下:
1.浏览器在发送真实HTTP请求之前先发送一个OPTIONS的预检请求,检测服务器端是否支持真实请求进行跨域资源访问。
真实请求的信息在OPTIONS请求中通过请求头中的Access-Control-Request-Method和Access-Control-Request-Headers字段来描述。此外与简单跨域请求一样,请求头中也会有Origin字段。
Origin: http://www.joker.com Access-Control-Request-Method: PUT Access-Control-Request-Headers: Header1,Header2
Origin
:必须字段,用于指定请求源。
Access-Control-Request-Method
:必须字段,用于描述真实请求的方法(PUT、DELETE等)。
Access-Control-Request-Headers
:指定真实请求会额外发送的请求头字段信息。
2.服务器端接到预检请求后,会检查了Origin、Access-Control-Request-Method和Access-Control-Request-Headers字段,检验是否允许跨源请求。
如果不允许该跨域请求,会返回一个正常的HTTP回应,但这个响应头信息没有包含Access-Control-Allow-Origin字段,浏览器就知道该域名不在许可范围内。
如果允许该跨域请求,就会在响应头中放入Access-Control-Allow-Origin、Access-Control-Allow-Methods和Access-Control-Allow-Headers,分别表示允许跨域资源请求的域、请求方法和请求头。此外,服务器端还可以在响应头中放入Access-Control-Max-Age,允许浏览器在指定时间内,无需再发送预检请求进行协商,直接用本次协商结果即可。
Access-Control-Allow-Origin: http://www.joker.com Access-Control-Allow-Methods: GET, POST, PUT Access-Control-Allow-Headers: Header1,Header2,Header3 Access-Control-Allow-Credentials: true Access-Control-Max-Age: 1728000
Access-Control-Allow-Methods
:该字段必需,它的值是逗号分隔的一个字符串,表明服务器支持的所有跨域请求的方法。注意,返回的是所有支持的方法,而不单是浏览器请求的那个方法。这是为了避免多次"预检"请求。
Access-Control-Allow-Headers
:如果浏览器请求包括Access-Control-Request-Headers字段,则Access-Control-Allow-Headers字段是必需的。它也是一个逗号分隔的字符串,表明服务器支持的所有头信息字段,不限于浏览器在"预检"中请求的字段。
Access-Control-Allow-Credentials
: 该字段与简单请求时的含义相同。它的值是一个布尔值,表示是否允许发送Cookie。默认情况下,Cookie不包括在CORS请求之中。设为true,即表示服务器明确许可,Cookie可以包含在请求中,一起发给服务器。这个值也只能设为true,如果服务器不要浏览器发送Cookie,删除该字段即可。
Access-Control-Max-Age
: 该字段可选,用来指定本次预检请求的有效期,单位为秒。上面结果中,有效期是20天(1728000秒),即允许缓存该条回应1728000秒(即20天),在此期间,不用发出另一条预检请求。
浏览器根据OPTIONS请求返回的结果来决定是否继续发送真实的请求进行跨域资源访问。这个过程对真实请求的调用者来说是透明的。
SpringBoot设置CORS的的本质都是通过设置响应头信息来告诉前端该请求是否支持跨域。
SpringBoot设置CORS的方式主要有以下三种。
1. 配置过滤器CorsFilter
@Configuration public class CorsConfig { @Bean CorsFilter corsFilter() { CorsConfiguration configuration = new CorsConfiguration(); configuration.setAllowedOrigins(Arrays.asList("*")); configuration.setAllowedMethods(Arrays.asList("*")); configuration.setAllowedHeaders(Arrays.asList("*")); configuration.setAllowCredentials(true); UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); source.registerCorsConfiguration("/**", configuration); return new CorsFilter(source); } }
2. 实现接口WebMvcConfigurer
@Configuration public class WebMvcConfig implements WebMvcConfigurer { @Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/**") .allowedOrigins("*") .allowedHeaders("*") .allowedMethods("*") .allowCredentials(true); } }
3. 使用注解@CrossOrigin
@CrossOrigin注解可以用在类或者方法上
用在控制器类上,表示 该类的所有方法都允许跨域
@RestController @CrossOrigin public class TestController { @GetMapping("test") public String test() { return "success"; } }
用在控制器方法上,表示该方法都允许跨域
@RestController public class TestController { @CrossOrigin @GetMapping("test") public String test() { return "success"; } }
@CrossOrigin注解源码
@Target({ElementType.TYPE, ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface CrossOrigin { /** * 这origins和value是一样的 * 允许来源域名的列表,例如 www.baidu.com,匹配的域名是跨域预请求Response头中的Access-Control-Aloow_origin字段值。 * 不设置确切值时默认支持所有域名跨域访问。 */ @AliasFor("origins") String[] value() default {}; @AliasFor("value") String[] origins() default {}; /** * 高版本下Spring2.4.4使用originPatterns而不是value和origins */ String[] originPatterns() default {}; /** * 跨域请求中允许的请求头中的字段类型, 该值对应跨域预请求Response头中的Access-Control-Allow-Headers字段值。 * 不设置确切值默认支持所有的header字段(Cache-Controller、Content-Language、Content-Type、Expires、Last-Modified、Pragma)跨域访问 */ String[] allowedHeaders() default {}; /** * 跨域请求请求头中允许携带的除Cache-Controller、Content-Language、Content-Type、Expires、Last-Modified、Pragma这六个基本字段之外的其他字段信息, * 对应的是跨域请求Response头中的Access-control-Expose-Headers字段值 */ String[] exposedHeaders() default {}; /** * 跨域HTTP请求中支持的HTTP请求类型(GET、POST...), * 不指定确切值时默认与 Controller 方法中的 methods 字段保持一致。 */ RequestMethod[] methods() default {}; /** * 浏览器是否将本域名下的cookie信息携带至跨域服务器中。默认携带至跨域服务器中,但要实现cookie共享还需要前端在AJAX请求中打开withCredentials属性。 * 该值对应的是是跨域请求 Response 头中的 'Access-Control-Allow-Credentials' 字段值。 */ String allowCredentials() default ""; /** * 该值的目的是减少浏览器预检请求/响应交互的数量。默认值1800s。设置了该值后,浏览器将在设置值的时间段内对该跨域请求不再发起预请求。 * 该值对应的是是跨域请求Response头中的Access-Control-Max-Age字段值,表示预检请求响应的缓存持续的最大时间。 */ long maxAge() default -1; }
위 내용은 교차 도메인 액세스를 허용하도록 SpringBoot에서 교차 도메인 필터를 구성하는 방법의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!