あなたが知らないSprigBootとVueの展開解決策
12304 ワード
前言
この間、会社の外部ネットワークが展開したデモンストレーション環境はすべてイントラネット環境に移行しました。すべての外部デモンストレーションの環境は外部ネットワークマッピングを申請してこそ、あるサービスにアクセスできます。私は1つの外部ネットワークアドレス
最近また一つのプロジェクトを作りました。ユーザーの体験を考慮して、展開の複雑さを減らすために、ウェブサーバをSpring Bootでウェブリソースにマッピングする方法を考えました。
条件が許容されています。または性能に対する要求が高いです。推薦は前後に分離して配置されています。inxはウェブサーバをしています。バックエンドはインターフェースサービスのみを提供しています。
以前に展開されたプロジェクトAの外部ネットワークアクセスアドレスは
例えば、以前のプロジェクトAのアクセスアドレスは、
現在Aのアクセスアドレスは
例えば、
フロントエンドは
本論文の内容 Ngixはvueプロジェクトを展開していますが、どうやって静的資源の損失を友好的に処理することができますか? SpringBootは、ウェブサーバの機能マッピングvueプロジェクトをウェブリソースとして提供し、vueルーティング転送index.を処理する。 デモコードのアドレス
Nginx部署Vueプロジェクト
この配置はtry_を使用しています。files内部のリダイレクトリソースは、ブラウザ側でリダイレクトが発生しない。
これはリダイレクトの構成です。
この考え方によって、すべてのリソースを転送することができます。トラフィックコードを変更する必要はなく、
Spring Boot展開Vueプロジェクト
SpringBootマッピング静的資源
アクセスエラーのジャンプは、インターフェース要求と静的リソースの要求を明確にして、acceptで判断できます。
ここで、あなたの知らないSprigBootとVueの展開解決策についての記事を紹介します。Spring BootとVueの展開内容については、以前の文章を検索したり、下記の関連記事を見たりしてください。これからもよろしくお願いします。
この間、会社の外部ネットワークが展開したデモンストレーション環境はすべてイントラネット環境に移行しました。すべての外部デモンストレーションの環境は外部ネットワークマッピングを申請してこそ、あるサービスにアクセスできます。私は1つの外部ネットワークアドレス
www.a.com
を使用して1つのイントラネットアドレスhttp://ip:port
にマッピングし、次いでこのアドレスhttp://ip:port
でインテンxをプロキシとして各グループのプロジェクトhttp://ipn:portn
に転送し、そのうち、いくつかの静的リソース404にも遭遇し、主にこの404問題を解決する。最近また一つのプロジェクトを作りました。ユーザーの体験を考慮して、展開の複雑さを減らすために、ウェブサーバをSpring Bootでウェブリソースにマッピングする方法を考えました。
条件が許容されています。または性能に対する要求が高いです。推薦は前後に分離して配置されています。inxはウェブサーバをしています。バックエンドはインターフェースサービスのみを提供しています。
以前に展開されたプロジェクトAの外部ネットワークアクセスアドレスは
http://ip1:8080
で、外部ネットワークマッピング後はhttp://ip/app1
にしかアクセスできませんでした。以前のプロジェクトBの外部ネットワークアクセスアドレスはhttp://ip1:8081
で、プロジェクトアクセスアドレスはhttp://ip/app2
です。これも大きな変動といえるが、切り替え後に遭遇する最初の問題は、静的リソース転送が404
をもたらすことである。例えば、以前のプロジェクトAのアクセスアドレスは、
http://ip1:8080
であり、文脈がない。現在Aのアクセスアドレスは
http://ip/app1
であり、ここではコンテキストアプリ1があり、いくつかのリソース404が生じる。例えば、
http://ip1:8080
はindex.htmlリソースを要求しましたが、今はhttp://ip/app1
にindex.までお願いするしかありません。
<!-- index.html -->
<!-- -->
<link href="/index.css" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="stylesheet">
以前のアクセスindex.css
アドレスはhttp://ip1:8080/index.css
であったが、http://ip/index.css
にアクセスするようになったので、実際のindex.cssアドレスはhttp://ip/app1/index.css
であった。フロントエンドは
vue
を使って作成しています。htmlの静的リソースパスはよく解決できます。webpackパッケージを変更すればいいです。
<!-- -->
<link href="/index.css" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="stylesheet">
<!-- -->
<link href="./index.css" rel="external nofollow" rel="stylesheet">
<!-- webpack -->
<link href="<%= BASE_URL %>index.css" rel="external nofollow" rel="stylesheet">
しかし、プロジェクトの中にはいくつかのコンポーネントの要求があります。しかし、コードを使いたくないです。webpackパッケージは動きたくないです。これらの需要に基づいて一つの方法を考えて解決します。本論文の内容
Nginx部署Vueプロジェクト
server {
listen 8087;
# , /app1 , /app1/ , /app1 。 ,
location / {
try_files $uri $uri/;
}
root /Users/zhangpanqin/staic/;
location ~ /(.*)/ {
index index.html /index.html;
try_files $uri $uri/ /$1/index.html;
}
}
/Users/zhangpanqin/staic/
は、appなどのプロジェクトリソースを/Users/zhangpanqin/staic/app
の下に配置する。アクセスアドレスはhttp://ip/8087/app
です。
<!DOCTYPE html>
<html lang="en">
<head>
<!-- BASE_URL vue.config.js publicPath-->
<link rel="icon" href="<%= BASE_URL %>favicon.ico" rel="external nofollow" >
<!-- , index.css -->
<link href="/index.css" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="stylesheet">
</head>
</html>
ブラウザでvueのルーティング/app/blog
を入力してもページにアクセスできるようにするためには、vue-router
のBase属性を追加する必要がある。
import Vue from 'vue';
import VueRouter from 'vue-router';
Vue.use(VueRouter);
const routes = [
{
path: '/',
name: 'Home',
component: () => import('@/views/Home.vue'),
},
{
path: '/blog',
name: 'Blog',
component: () => import('@/views/Blog.vue'),
},
{
//
path: '*',
name: 'Error404',
component: () => import('@/views/Error404.vue'),
}
];
const router = new VueRouter({
// , vue mode 。
// https://cli.vuejs.org/zh/guide/mode-and-env.html
// https://router.vuejs.org/zh/api/#base
base: process.env.VUE_APP_DEPLOY_PATH,
mode: 'history',
routes,
});
export default router;
http://localhost:8087/app/index.css
はcssの本当のアドレスである。だから、これらは/app
で始まる資源ではなく、/app
を加えればいいと考えました。クッキーだけができると思いました。x_vue_path
は、各プロジェクトのパスを記録し、静的リソースをこの経路で探します。この配置はtry_を使用しています。files内部のリダイレクトリソースは、ブラウザ側でリダイレクトが発生しない。
# gzip , epoll
server {
listen 8087;
# , /app1 , /app1/ , /app1 。 ,
location / {
try_files $uri $uri/;
}
root /Users/zhangpanqin/staic/;
# (.*) , app1 app2
location ~ /(.*)/.*/ {
index index.html /index.html;
add_header Set-Cookie "x_vue_path=/$1;path=/;";
# /Users/zhangpanqin/staic/+/$1/index.html index.html
try_files $uri $uri/ /$1/index.html @404router;
}
# , 。
location ~ (.css|js)$ {
try_files $uri $cookie_x_vue_path/$uri @404router;
}
location @404router {
return 404;
}
}
これはリダイレクトの構成です。
server {
listen 8087;
root /Users/zhangpanqin/staic/;
location ~ /(.*)/.*/? {
index index.html /index.html;
add_header Set-Cookie "x_vue_path=/$1;path=/;";
try_files $uri $uri/ /$1/index.html @404router;
}
location ~ (.css|js)$ {
# /app/index.css ,
rewrite ^($cookie_x_vue_path)/.* $uri break;
# /index.css 302 /app/index.css
rewrite (.css|js)$ $cookie_x_vue_path$uri redirect;
}
location @404router {
return 404;
}
}
この考え方によって、すべてのリソースを転送することができます。トラフィックコードを変更する必要はなく、
$cookie_x_vue_path/$uri
にvue-router
ベースのルートを追加するだけです。Spring Boot展開Vueプロジェクト
base
が通りました。SpringBootはなぞなぞによって芦の絵瓢を描けばいいです。それともjavaの書く快適さです。debugができます。ハハ。SpringBootマッピング静的資源
@Configuration
public class VueWebConfig implements WebMvcConfigurer {
/**
*
* file:./static/ user.dir ,jar static
*/
private static final String[] CLASSPATH_RESOURCE_LOCATIONS = {"file:./static/", "classpath:/META-INF/resources/",
"classpath:/resources/", "classpath:/static/", "classpath:/public/"};
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
//
CacheControl cacheControl = CacheControl.maxAge(5, TimeUnit.HOURS).cachePublic();
registry.addResourceHandler("/**").addResourceLocations(CLASSPATH_RESOURCE_LOCATIONS).setCacheControl(cacheControl);
}
@Override
public void addInterceptors(InterceptorRegistry registry) {
// , cookie
registry.addInterceptor(new VueCookieInterceptor()).addPathPatterns("/test/**");
}
// vue ,
@Bean
public VueErrorController vueErrorController() {
return new VueErrorController(new DefaultErrorAttributes());
}
}
プロジェクトの静的リソースパスにクッキーを追加します。
public class VueCookieInterceptor implements HandlerInterceptor {
public static final String VUE_HTML_COOKIE_NAME = "x_vue_path";
public static final String VUE_HTML_COOKIE_VALUE = "/test";
/**
* /test cookie
*/
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
final Cookie cookieByName = getCookieByName(request, VUE_HTML_COOKIE_NAME);
if (Objects.isNull(cookieByName)) {
final Cookie cookie = new Cookie(VUE_HTML_COOKIE_NAME, VUE_HTML_COOKIE_VALUE);
// url
cookie.setPath("/");
cookie.setHttpOnly(true);
response.addCookie(cookie);
}
return true;
}
public static Cookie getCookieByName(HttpServletRequest httpServletRequest, String cookieName) {
final Cookie[] cookies = httpServletRequest.getCookies();
if (Objects.isNull(cookieName) || Objects.isNull(cookies)) {
return null;
}
for (Cookie cookie : cookies) {
final String name = cookie.getName();
if (Objects.equals(cookieName, name)) {
return cookie;
}
}
return null;
}
}
リソースの転送のためにエラーが発生したことを要求します。アクセスエラーのジャンプは、インターフェース要求と静的リソースの要求を明確にして、acceptで判断できます。
@RequestMapping("/error")
public class VueErrorController extends AbstractErrorController {
private static final String ONLINE_SAIL = VUE_HTML_COOKIE_NAME;
private static final String ERROR_BEFORE_PATH = "javax.servlet.error.request_uri";
public VueErrorController(DefaultErrorAttributes defaultErrorAttributes) {
super(defaultErrorAttributes);
}
@Override
public String getErrorPath() {
return "/error";
}
@RequestMapping
public ModelAndView errorHtml(HttpServletRequest httpServletRequest, HttpServletResponse response, @CookieValue(name = ONLINE_SAIL, required = false, defaultValue = "") String cookie) {
final Object attribute = httpServletRequest.getAttribute(ERROR_BEFORE_PATH);
if (cookie.length() > 0 && Objects.nonNull(attribute)) {
response.setStatus(HttpStatus.OK.value());
String requestURI = attribute.toString();
// vue ,
if (!requestURI.startsWith(cookie)) {
ModelAndView modelAndView = new ModelAndView();
modelAndView.setStatus(HttpStatus.OK);
// , , redirect
String viewName = "forward:" + cookie + requestURI;
modelAndView.setViewName(viewName);
return modelAndView;
}
}
ModelAndView modelAndView = new ModelAndView();
modelAndView.setStatus(HttpStatus.OK);
modelAndView.setViewName("forward:/test/index.html");
return modelAndView;
}
// accept application/json , json
@RequestMapping(produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<Map<String, Object>> error(HttpServletRequest request) {
HttpStatus status = getStatus(request);
if (status == HttpStatus.NO_CONTENT) {
return new ResponseEntity<>(status);
}
final Map<String, Object> errorAttributes = getErrorAttributes(request, true);
return new ResponseEntity<>(errorAttributes, status);
}
最初のページへジャンプ
@Controller
public class IndexController {
@RequestMapping(value = {"/test", "/test"})
public String index() {
return "forward:/test/index.html";
}
}
この文章は張攀欽のブログwww.mflyyou.cn/によって作成されます。転載・引用は自由ですが、著者と署名し、出典を明記してください。ここで、あなたの知らないSprigBootとVueの展開解決策についての記事を紹介します。Spring BootとVueの展開内容については、以前の文章を検索したり、下記の関連記事を見たりしてください。これからもよろしくお願いします。