Vue.js学习(三)—— 分别从前后端Nginx解决SpringBoot+vue.js项目中的跨域问题
2021-04-21 18:28
标签:客户端 this ide 直接 font 运行命令 sdn response port 一、什么是跨域 (1)跨域 由于浏览器同源策略,凡是发送请求url的协议、域名、端口三者之间任意一个与当前页面地址不同即为跨域。存在跨域的情况: (2)url格式 一般格式:协议 + 域名(子域名 + 主域名) + 端口号 + 资源地址 示例: 只要协议,子域名,主域名,端口号这四项组成部分中有一项不同,就可以认为是不同的域,不同的域之间互相访问资源,就被称之为跨域。 (3) 我们可以理解为:如果一个请求需要允许跨域访问,则需要在http头中设置Access-Control-Allow-Origin来决定需要允许哪些站点来访问。如假设需要允许https://www.dustyblog.c这个站点的请求跨域,则可以设置: Access-Control-Allow-Origin:https://www.dustyblog.cn。 二、后端SpringBoot解决 1、方案一:CORS局部配置-使用@CrossOrigin注解 (1)在 该类下的所有接口都可以通过跨域访问 这里指定当前的 (2)在方法上使用 这里指定只有该方法可以处理 2、方案二:CORS局部配置-手工设置响应头(局部跨域) 3、方案三: Spring Boot 2.0中已经废弃WebMvcConfigurerAdapter类, 开发人员可以通过实现 4、方案四: 通过实现 5、方案五: 或者 或者 三、前段Vue.js解决 解决方案:采用 (1)打开项目根目录下的 注意:每次修改配置文件需要重启服务才能生效:npm run dev (2)通过axios来实现发送访问 在main.js中导入已安装好的axios,并挂载到原型上 (3)通过this.$axios.get().then()来实现数据请求 注意:此种跨域解决方案,只能适用于测试阶段,因为项目打包发布之后,由于proxyTable不能再使用,所以无法跨域了。正式环境中,前端项目和后端项目放在一起就不存在跨域问题了。如果非要跨域,则可以采取上面的后端解决方法或者下面的Nginx替代前端的proxyTable代理功能。 三、Nginx解决生产环境跨域问题 1、安装好Nginx之后,打开安装目录下的 注:每次修改配置文件需要重启服务才能生效 2、Nginx常用相关命令: 需要在Nginx文件目录下运行命令行工具 (1)启动 (2)停止 注:stop是快速停止nginx,可能并不保存相关信息;quit是完整有序的停止nginx,并保存相关信息。 (3)重新载入 (4)重新打开日志文件 (5)查看版本 Vue.js学习(三)—— 分别从前后端Nginx解决SpringBoot+vue.js项目中的跨域问题 标签:客户端 this ide 直接 font 运行命令 sdn response port 原文地址:https://www.cnblogs.com/javahr/p/13280643.html网络协议不同,如http协议访问https协议。
端口不同,如80端口访问8080端口。
域名不同,如qianduanblog.com访问baidu.com。
子域名不同,如abc.qianduanblog.com访问def.qianduanblog.com。
域名和域名对应ip,如www.a.com访问20.205.28.90.
https://www.dustyblog.cn:8080/say/Hello
是由https
+ www
+ dustyblog.cn
+ 8080
+ say/Hello
组成。Cors
CORS
全称为Cross Origin Resource Sharing
(跨域资源共享), 每一个页面需要返回一个名为Access-Control-Allow-Origin
的http头来允许外域的站点访问,你可以仅仅暴露有限的资源和有限的外域站点访问。Controller
上使用@CrossOrigin
注解@RequestMapping("/demo2")
@RestController
//@CrossOrigin //所有域名均可访问该类下所有接口
@CrossOrigin("https://blog.csdn.net") // 只有指定域名可以访问该类下所有接口
public class CorsTest2Controller {
@GetMapping("/sayHello")
public String sayHello() {
return "hello world --- 2";
}
}
CorsTest2Controller
中所有的方法可以处理https://csdn.net
域上的请求,其他域名不能请求@CrossOrigin
注解@RequestMapping("/preUser")
@CrossOrigin("https://blog.csdn.net")
public Map
Map
map.put("preUser","success");
return map;
}https://csdn.net
域上的请求,其他域名不能请求@RequestMapping("/hello")
@ResponseBody
public String index(HttpServletResponse response){
response.addHeader("Access-Control-Allow-Origin", "http://localhost:8080");
return "Hello World";
}
Access-Control-Allow-Origin 表示允许哪些原始域进行跨域访问。
Access-Control-Allow-Credentials表示是否允许客户端获取用户凭据。
Access-Control-Allow-Methods 表示允许哪些跨域请求的提交方式。(例如GET/POST)
Access-Control-Expose-Headers 表示允许暴露哪些头部信息给客户端。
Access-Control-Max-Age 表示预检请求 [Preflight Request] 的最大缓存时间。
CORS
全局配置-实现WebMvcConfigurer(本人习惯用法)
WebMvcConfigurer
接口实现相应的功能。CorsConfig.java
:/**
* 跨域配置
*/
@Configuration
public class CorsConfig implements WebMvcConfigurer {
@Bean
public WebMvcConfigurer corsConfigurer()
{
return new WebMvcConfigurer() {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**").
allowedOrigins("https://www.dustyblog.cn"). //允许跨域的域名,可以用*表示允许任何域名使用
allowedMethods("*"). //允许任何方法(post、get等)
allowedHeaders("*"). //允许任何请求头
allowCredentials(true). //带上cookie信息
exposedHeaders(HttpHeaders.SET_COOKIE).maxAge(3600L); //maxAge(3600)表明在3600秒内,不需要再发送预检验请求,可以缓存该结果
}
};
}
}
CORS
全局配置-使用Filter方式进行设置(过滤器实现)Fiter
接口在请求中添加一些Header
来解决跨域的问题,向请求端设置Response Header(响应头部)的Access-Control-Allow-Origin属性声明允许跨域访问。@Component
public class CorsFilter implements Filter {
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
HttpServletResponse res = (HttpServletResponse) response;
res.addHeader("Access-Control-Allow-Credentials", "true");
res.addHeader("Access-Control-Allow-Origin", "*");
res.addHeader("Access-Control-Allow-Methods", "GET, POST, DELETE, PUT");
res.addHeader("Access-Control-Allow-Headers", "Content-Type,X-CAF-Authorization-Token,sessionToken,X-TOKEN");
if (((HttpServletRequest) request).getMethod().equals("OPTIONS")) {
response.getWriter().println("ok");
return;
}
chain.doFilter(request, response);
}
@Override
public void destroy() {
}
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
}
CORS
全局配置-继承使用Spring Web中的CorsFilterpackage com.garyond.hurricane.config;
import org.springframework.stereotype.Component;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;
import java.util.Arrays;
/**
* 跨域访问配置
*
* @author Garyond
*/
@Component
public class CustomCorsFilter extends CorsFilter {
public CustomCorsFilter() {
super(configurationSource());
}
private static UrlBasedCorsConfigurationSource configurationSource() {
CorsConfiguration config = new CorsConfiguration();
config.setAllowCredentials(true);
config.addAllowedOrigin("*");
config.addAllowedHeader("*");
config.setMaxAge(36000L);
config.setAllowedMethods(Arrays.asList("GET", "HEAD", "POST", "PUT", "DELETE", "OPTIONS"));
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/v1/**", config);
return source;
}
}
package com.ranxx.conf;
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;
/**
* 跨域问题
*
* @author mousejoo
*/
@Configuration
public class CorsConfig {
private CorsConfiguration buildConfig() {
CorsConfiguration corsConfiguration = new CorsConfiguration();
corsConfiguration.addAllowedOrigin("*"); // 1 允许任何域名使用
corsConfiguration.addAllowedHeader("*"); // 2 允许任何头
corsConfiguration.addAllowedMethod("*"); // 3 允许任何方法(post、get等)
return corsConfiguration;
}
@Bean
public CorsFilter corsFilter() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", buildConfig()); // 4
return new CorsFilter(source);
}
}
package com.example.longecological.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 GlobalCorsConfig {
@Bean
public CorsFilter corsFilter() {
//1.添加CORS配置信息
CorsConfiguration config = new CorsConfiguration();
//放行哪些原始域
config.addAllowedOrigin("*");
//是否发送Cookie信息
config.setAllowCredentials(true);
//放行哪些原始域(请求方式)
config.addAllowedMethod("*");
//放行哪些原始域(头部信息)
config.addAllowedHeader("*");
//暴露哪些头部信息(因为跨域访问默认不能获取全部头部信息)
config.addExposedHeader("content-type");
//2.添加映射路径
UrlBasedCorsConfigurationSource configSource = new UrlBasedCorsConfigurationSource();
configSource.registerCorsConfiguration("/**", config);
//3.返回新的CorsFilter.
return new CorsFilter(configSource);
}
}
proxyTable
配置代理跨域config/index.js
文件,参考以下proxyTable
部分的配置:module.exports = {
dev: {
// Paths
assetsSubDirectory: ‘static‘,
assetsPublicPath: ‘/‘,
// *********代理跨域 主要代码**********
proxyTable: {
‘/api‘: { //匹配接口路径中的 /api,可以随意命名
target: ‘http://********:9001/api‘, //目标接口地址,设置调用的接口域名和端口号 别忘了加http、https
changeOrigin: true, //是否跨域
secure: true, // 允许https请求,https必须添加这个设置
pathRewrite: {
‘^/api‘: ‘‘ // 路径重写 将 target 中的目标接口地址重写为 /api,
这里理解成用‘/api’代替target里面的地址,后面组件中我们掉接口时直接用api代替 比如我要调用‘http://40.00.100.100:3002/user/add‘,直接写‘/api/user/add’即可
} } }, }
import Axios from ‘axios‘ //导入axios
//将axios挂载到原型上
Vue.prototype.$axios = Axios;
//发送get请求
show() {
//用/api來代理‘http://localhost:8083‘
this.$axios
.get("/api/selectall")
.then(res => {
this.list = res.data.result;
// }
})
.catch(e => {
console.log(e);
});
},
//发送post请求
add() {
this.$axios({
method: "post",
url: "/api/saveinfo",
params: {
name: this.name //传递的参数
}
}).then(res => {
this.show();
});
},
conf/nginx.conf
文件,参考以下server
的简单配置:server {
listen 9091; #监听的端口
server_name localhost; #服务器名称
#charset koi8-r;
#access_log logs/host.access.log main;
location / {
root E:\hld-work\university\dist; #项目物理路径
index index.html index.htm; #项目的默认首页
}
location /api { #检测并替换接口内的字符串
proxy_pass http://**********:9001/api; #跨域访问的目标URL
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
client_max_body_size 100m;
}
}
start nginx 或 nginx.exe
nginx.exe -s stop 或 ginx.exe -s quit
nginx.exe -s reload
nginx.exe -s reopen
nginx -v
文章标题:Vue.js学习(三)—— 分别从前后端Nginx解决SpringBoot+vue.js项目中的跨域问题
文章链接:http://soscw.com/index.php/essay/77721.html