# 前端项目发布
前端项目的环境配置就在 js/app.js 文件中
serverUrl: "http://192.168.56.107:8080/foodie-dev-api", // 接口服务接口地址
paymentServerUrl: "http://payment.t.mukewang.com/foodie-payment", // 支付中心服务地址
shopServerUrl: "http://192.168.56.105:8080/foodie-shop/", // 门户网站地址
centerServerUrl: "http://192.168.56.105:8080/foodie-center/", // 用户中心地址
cookieDomain: "",
2
3
4
5
foodie-center 和 foodie-shop 项目中都需要改成上面的配置,下面的配置没有修改说明:
- cookieDomain:cookie 域,笔者这里是虚拟机部署,就和开发环境一样重置为空字符串
- paymentServerUrl:没有自有的支付资格,也用视频中线上的地址
部署到服务器后,访问 http://192.168.56.105:8080/foodie-shop/
打开控制台发现跨域了
Access to XMLHttpRequest at 'http://192.168.56.107:8080/foodie-dev-api/index/cats' from origin 'http://192.168.56.105:8080' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
从 http://192.168.56.105:8080
发起的 js 请求 http://192.168.56.107:8080/foodie-dev-api/index/cats
跨域了
# 跨域解决
开发的时候配置过了,只不过限制了能访问的域名
package cn.mrcode.foodiedev.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;
/**
* 跨域配置
*
* @author mrcode
* @date 2021/2/13 16:27
*/
@Configuration
public class CorsConfig {
@Bean
public CorsFilter corsFilter() {
CorsConfiguration config = new CorsConfiguration();
// 设置运行跨域的地址,也可以使用 * 代替允许所有地址
config.addAllowedOrigin("http://localhost:8080");
// 是否运行携带 cookie 相关信息
// 在前端也有的框架可以配置这一样,前端是否允许跨域的时候携带:axios.defaults.withCredentials = true;
config.setAllowCredentials(true);
// 允许访问所有的 http 请求方式,如 get、post
config.addAllowedMethod("*");
config.addAllowedHeader("*");
// 为 url 添加映射路径
// 允许所有路径使用该配置
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", config);
return new CorsFilter(source);
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
这里再增加一个线上的域名就可以了
config.addAllowedOrigin("http://192.168.56.105:8080");
config.addAllowedOrigin("http://192.168.56.105"); // 为以后做准备
2
# 关于虚拟机线上环境 cookie 设置不成功说明
由于不熟悉 http 协议,笔者找了很久才找到问题,具体做法是:
在登录页登录成功之后不进行跳转,停留在当前页面,就能看到发出的 js 请求
js 请求中发现了问题
可以看到,发出去了的请求是成功了的,也有 cookie 从服务端被设置,但是他的 Domain=192.168.56.107 这个 IP 是线上环境的后端 api 服务器地址,与前端项目 192.168.56.105 不匹配。
另外 Chrome 浏览器新版本新增了一个
SameSite
属性,他的格式如下,那么我们需要改动代码Set-Cookie: CookieName=CookieValue; SameSite=None;
1找到后端源码中,设置 cookie 的工具类中有如下的代码
cn.mrcode.foodiedev.common.util.CookieUtils#doSetCookie(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse, java.lang.String, java.lang.String, int, boolean) private static final void doSetCookie(HttpServletRequest request, HttpServletResponse response, String cookieName, String cookieValue, int cookieMaxage, boolean isEncode) { try { if (cookieValue == null) { cookieValue = ""; } else if (isEncode) { cookieValue = URLEncoder.encode(cookieValue, "utf-8"); } Cookie cookie = new Cookie(cookieName, cookieValue); if (cookieMaxage > 0) cookie.setMaxAge(cookieMaxage); if (null != request) {// 设置域名的cookie String domainName = getDomainName(request); logger.info("========== domainName: {} ==========", domainName); // 这里不是 localhost 才设置为后端的域名 if (!"localhost".equals(domainName)) { cookie.setDomain(domainName); } } cookie.setPath("/"); response.addCookie(cookie); } catch (Exception e) { e.printStackTrace(); } }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27由于 Cookie 类不支持 SameSite,那么这里就需要我们自己拼接 cookie 然后放到 header 中,代码如下
private static final void doSetCookie(HttpServletRequest request, HttpServletResponse response, String cookieName, String cookieValue, int cookieMaxage, boolean isEncode) { try { if (cookieValue == null) { cookieValue = ""; } else if (isEncode) { cookieValue = URLEncoder.encode(cookieValue, "utf-8"); } ResponseCookie.ResponseCookieBuilder rr = ResponseCookie.from(cookieName, cookieValue) .domain("") .maxAge(cookieMaxage) .path("/") .httpOnly(false) .secure(false) // 是否允许 js 读取,这里貌似要设置成 true .sameSite("None"); response.addHeader("Set-Cookie", rr.build().toString()); } catch (Exception e) { e.printStackTrace(); } } // org.springframework.http.ResponseCookie 类
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21这个代码设置之后,还是被谷歌浏览器拒绝了,应该是要求是 https 链接才可以。
笔者捣鼓了很长时间:
- domain 不设置,跨域环境下 cookie 不生效,不支持 ip,只支持域名
- sameSite 属性设置后,需要设置 secure 属性,并且需要 https 链接
到最后都没有搞定,这里暂时就不解决这个了,后面还需要换成 nginx 来代理,就没有跨域问题了
跨域的知识笔者懵逼了,后来又尝试过在本地 hosts 中使用域名来访问目标 IP,但是最后测试出来的结果没有报错,但是也看不到 cookie 的响应,算了,不搞跨域了