这里写目录标题
跨域(前后端分离,微服务)
什么是跨域?
跨域是指从一个域名的网页去请求另一个域名的资源。比如从 www.baidu.com 页面去请求 www.google.com 的资源。但是一般情况下不能这么做,它是由 浏览器的同源策略造成的,是浏览器对 JavaScript 施加的安全限制。跨域的严格一点的定义是:只要 协议,域名,端口有任何一个的不同,就被当作是跨域. 所谓同源是指,域名,协议,端口均相同,只要有一个不同,就是跨域
为什么浏览器要限制跨域访问呢?
原因就是安全问题:如果一个网页可以随意地访问另外一个网站的资源,那么就 有可能在客户完全不知情的情况下出现安全问题。比如下面的操作就有安全问题
1.用户访问 www.mybank.com ,登陆并进行网银操作,这时 cookie 啥的都生 成并存放在浏览器
2.用户突然想起件事,并迷迷糊糊地访问了一个邪恶的网站 www.xiee.com这时该网站就可以在它的页面中,拿到银行的 cookie,比如用户名,登陆 token 等,然后发起对 www.mybank.com 的操作。
3.如果这时浏览器不予限制,并且银行也没有做响应的安全处理的话,那么用户 的信息有可能就这么泄露了。
为什么要跨域?
既然有安全问题,那为什么又要跨域呢? 有时公司内部有多个不同的子域,比 如一个location.company.com ,而应用是放在 app.company.com , 这时想 从 app.company.com 去访问 location.company.com 的资源就属于跨域
解决跨域问题的方法 :
1. 前端解决
2. 后端 (这里主要介绍后端解决)
跨域资源共享(CORS)
W3C 的 Web 工作组推荐了一种新的机制,即跨域资源共享(Cross-origin Resource Sharing),简称 CORS。其实这个机制就是实现了跨站访问控制, 使得安全地进行跨站数据传输成为可能。 服务器端对于 CORS 的支持,主要就是通过设置 Access-Control-Allow-Origin 来进行的。如果浏览器检测到相应的设置,就可以允许 Ajax 进行跨域的访问。只需要在后台中加上响应头来允许域请求!在被请求的 Response header 中加 入以下设置,就可以实现跨域访问了!
Spring 项目中的解决方法:
方式 1:手工设置响应头(HttpServletResponse )
方式 2:使用注解(@CrossOrigin)
方式 3:返回新的 CorsFilter
-
手工设置响应头(局部跨域 ) 使用 HttpServletResponse 对象添加响应头 (Access-Control-Allow-Origin)来授权原始域,这里 Origin 的值也可以设 置为"*" ,表示全部放行。
@RequestMapping("/hello")
@ResponseBody
public String index(HttpServletResponse response){
response.addHeader(“Access-Control-Allow-Origin”,
“http://127.0.0.1:8848”);
return “Hello World”;
}
2.使用注解(局部跨域)
在方法上(@RequestMapping)使用注解 @CrossOrigin :
@RequestMapping("/hello")@ResponseBody
@CrossOrigin(“http://127.0.0.1:8848”)
public String index( ){
return “Hello World”;
}
或者在控制器(@Controller)上使用注解 @CrossOrigin
3.返回新的 CorsFilter(全局跨域)
在任意配置类,返回一个新的 CorsFilter Bean,并添加映射路径和具体的 CORS 配置信息。
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;
import java.util.Collections;
@Configuration
public class CorsConfig {
@Bean
public CorsFilter corsFilter() {CorsConfiguration corsConfiguration = new CorsConfiguration();
//1,允许任何来源
corsConfiguration.setAllowedOriginPatterns(Collections.singletonList("*"));
//2,允许任何请求头
corsConfiguration.addAllowedHeader(CorsConfiguration.ALL);
//3,允许任何方法
corsConfiguration.addAllowedMethod(CorsConfiguration.ALL);
//4,允许凭证
corsConfiguration.setAllowCredentials(true);
UrlBasedCorsConfigurationSource source
= new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", corsConfiguration);
return new CorsFilter(source);
}
}
package com.ffyc.back.demo.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;
import java.util.Collections;
@Configuration
public class CorsConfig {
@Bean
public CorsFilter corsFilter() {
CorsConfiguration corsConfiguration = new CorsConfiguration();
//1,允许任何来源
corsConfiguration.setAllowedOriginPatterns(Collections.singletonList("*"));
//2,允许任何请求头
corsConfiguration.addAllowedHeader(CorsConfiguration.ALL);
// 3,允许任何方法
corsConfiguration.addAllowedMethod(CorsConfiguration.ALL);
//4,允许凭证
corsConfiguration.setAllowCredentials(true);
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", corsConfiguration);
return new CorsFilter(source);
}
}