前后端跨域问题

跨域问题

1、什么是跨域??

指的是浏览器不能执行其他网站的脚本,也就是前后端的代码运行在不同的服务器上的时候就会出现跨域问题,它是由浏览器的同源策略造成的,是浏览器对javascript施加的安全限制。

2、什么是同源策略?

同源策略是一种约定,由Netscape公司1995年引入浏览器,它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,浏览器很容易受到XSS、CSFR等攻击。

所谓同源是指"协议+域名+端口"三者相同,即协议、域名、端口

地址:http://www.baidu.com:8080/item

http是协议,www.baidu.com是域名,8080是端口,只有这三种都相同,才是同源

同源策略限制以下几种行为:

  • Cookie、LocalStorage 和 IndexDB 无法读取
  • DOM和JS对象无法获得
  • AJAX 请求不能发送

3、跨域资源共享(CORS)

CORS是一个W3C标准,全称是"跨域资源共享"(Cross-origin resource sharing)。
它允许浏览器向跨源服务器,发出XMLHttpRequest请求,从而克服了AJAX只能同源使用的限制。
CORS需要浏览器和服务器同时支持。目前,所有浏览器都支持该功能,IE浏览器不能低于IE10。

浏览器将CORS跨域请求分为简单请求和非简单请求。

只要同时满足一下两个条件,就属于简单请求

(1)使用下列方法之一:

  • head
  • get
  • post

(2)请求的Heder是

  • Accept
  • Accept-Language
  • Content-Language
  • Content-Type: 只限于三个值:application/x-www-form-urlencoded、multipart/form-data、text/plain

不同时满足上面的两个条件,就属于非简单请求。浏览器对这两种的处理,是不一样的。

简单请求

对于简单请求,浏览器直接发出CORS请求。具体来说,就是在头信息之中,增加一个Origin字段。

GET /cors HTTP/1.1
Origin: http://api.item.com
Host: api.item.com
Accept-Language: en-US
Connection: keep-alive
User-Agent: Mozilla/5.0...

上面的头信息中,Origin字段用来说明,本次请求来自哪个源(协议 + 域名 + 端口)。服务器根据这个值,决定是否同意这次请求。

CORS请求设置的响应头字段,都以 Access-Control-开头:

1)Access-Control-Allow-Origin:必选

它的值要么是请求时Origin字段的值,要么是一个*,表示接受任意域名的请求。

2)Access-Control-Allow-Credentials:可选

它的值是一个布尔值,表示是否允许发送Cookie。默认情况下,Cookie不包括在CORS请求之中。设为true,即表示服务器明确许可,Cookie可以包含在请求中,一起发给服务器。这个值也只能设为true,如果服务器不要浏览器发送Cookie,删除该字段即可。

3)Access-Control-Expose-Headers:可选

CORS请求时,XMLHttpRequest对象的getResponseHeader()方法只能拿到6个基本字段:Cache-Control、Content-Language、Content-Type、Expires、Last-Modified、Pragma。如果想拿到其他字段,就必须在Access-Control-Expose-Headers里面指定。上面的例子指定,getResponseHeader(‘FooBar’)可以返回FooBar字段的值。

非简单请求

非简单请求是那种对服务器有特殊要求的请求,比如请求方法是PUT或DELETE,或者Content-Type字段的类型是application/json。非简单请求的CORS请求,会在正式通信之前,增加一次HTTP查询请求,称为"预检"请求(preflight)。

预检请求

预检"请求用的请求方法是OPTIONS,表示这个请求是用来询问的。请求头信息里面,关键字段是Origin,表示请求来自哪个源。除了Origin字段,"预检"请求的头信息包括两个特殊字段。

OPTIONS /cors HTTP/1.1
Origin: http://api.item.com
Access-Control-Request-Method: PUT
Access-Control-Request-Headers: X-Custom-Header
Host: api.item.com
Accept-Language: en-US
Connection: keep-alive
User-Agent: Mozilla/5.0..

1)Access-Control-Request-Method:必选

用来列出浏览器的CORS请求会用到哪些HTTP方法,上例是PUT。

2)Access-Control-Request-Headers:可选

该字段是一个逗号分隔的字符串,指定浏览器CORS请求会额外发送的头信息字段,上例是X-Custom-Header。

预检请求的回应

服务器收到"预检"请求以后,检查了Origin、Access-Control-Request-Method和Access-Control-Request-Headers字段以后,确认允许跨源请求,就可以做出回应。

HTTP回应中,除了关键的是Access-Control-Allow-Origin字段,其他CORS相关字段如下:

1)Access-Control-Allow-Methods:必选

它的值是逗号分隔的一个字符串,表明服务器支持的所有跨域请求的方法。注意,返回的是所有支持的方法,而不单是浏览器请求的那个方法。这是为了避免多次"预检"请求。

2)Access-Control-Allow-Headers

如果浏览器请求包括Access-Control-Request-Headers字段,则Access-Control-Allow-Headers字段是必需的。它也是一个逗号分隔的字符串,表明服务器支持的所有头信息字段,不限于浏览器在"预检"中请求的字段。

3)Access-Control-Allow-Credentials:可选

该字段与简单请求时的含义相同。

4)Access-Control-Max-Age:可选

用来指定本次预检请求的有效期,单位为秒。

4、跨域解决

SpringBoot后端处理

环境准备:

  • 后端:SpringBoot 接口 :http://1oca7host:8181/1ist
  • 前端:Vue 接口 :http://1oca7host:8080

前端请求后端浏览器控制台出现错误:

Access to XMLHttpRequest at 'http://1oca7host:8181/1ist' fromorigin 'http: //localhost:8080' has been blocked by coRs policy:No 'Access-contro1-A11ow-origin' header is present on the  requested resource.

CROS: Cross Origin Resource Sharing

Spring Boot项目中解决跨域的3种方案

1、在目标方法上添加 @CrossOrigin 注解

@RestController
@CrossOrigin
public class HelloController {
    
	@GetMapping("/hello")
	public String hello(){
		return "hello,kuangshen";
	}
}

2、添加CrossOrigin过滤器

package com.wkb.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;

/**
 * 

* 添加跨域过滤器 *

*/
@Configuration public class CrossConfig { @Bean public CorsFilter corsFilter() { CorsConfiguration corsConfiguration = new CorsConfiguration(); corsConfiguration.addAllowedOrigin("*");//允许哪些域名访问 corsConfiguration.addAllowedHeader("*");//允许哪些请求头访问 corsConfiguration.addAllowedMethod("*");//允许哪些方法访问 UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); source.registerCorsConfiguration("/**", corsConfiguration); return new CorsFilter(source); } }

3、实现WebMvcConfigure接口,重写addCorsMappings,实现跨域解决

package com.wkb.config;

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

/**
 * 

* 实现 WebMvcConfigurer接口,重写addCorsMappings,实现跨域解决 *

*/
@Configuration public class CrossConfiguration implements WebMvcConfigurer { @Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/**") .allowedOrigins("*") .allowedHeaders("*") .allowedMethods("GET","POST","PUT","DELETE","HEAD","OPTIONS") .allowCredentials(true) //是否允许携带cookie .maxAge(3600); } }

你可能感兴趣的:(springboot,Java基础,java,spring,boot)