Skip to content

Commit 15baa30

Browse files
committed
fix: server.js
1 parent 8a8c88e commit 15baa30

File tree

3 files changed

+212
-64
lines changed

3 files changed

+212
-64
lines changed

Diff for: package.json

+1
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
"next": "^12.1.6",
3939
"next-i18next": "^15.3.0",
4040
"nprogress": "^0.2.0",
41+
"pino-http": "^10.2.0",
4142
"raw-loader": "^4.0.2",
4243
"rc-image": "^7.0.0-2",
4344
"rc-util": "^5.34.1",

Diff for: server.js

+60-63
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
const express = require('express');
33
const next = require('next');
44
const cookieParser = require('cookie-parser');
5+
const pino = require('pino-http')();
56

67
const app = next({ dev: false });
78
const handle = app.getRequestHandler();
@@ -11,81 +12,77 @@ const DEFAULT_LOCALE = 'zh';
1112
const FALLBACK_LOCALE = 'en';
1213
const SUPPORTED_LOCALES = ['zh', 'en'];
1314

15+
const isStaticRoute = (url) => url.startsWith('/_next') || url.startsWith('/static');
16+
17+
const getLocaleFromUrl = (path) => {
18+
const urlParts = path.split('/');
19+
return SUPPORTED_LOCALES.includes(urlParts[1]) ? urlParts[1] : null;
20+
};
21+
22+
const determineLocale = (req, urlLocale) => {
23+
let locale = req.cookies.locale;
24+
if (!locale) {
25+
const browserLocale = req.acceptsLanguages(SUPPORTED_LOCALES);
26+
locale = urlLocale || browserLocale || FALLBACK_LOCALE;
27+
if (browserLocale && browserLocale !== 'zh') {
28+
locale = FALLBACK_LOCALE;
29+
}
30+
}
31+
return SUPPORTED_LOCALES.includes(locale) ? locale : FALLBACK_LOCALE;
32+
};
33+
34+
const handleRedirect = (req, res, locale, urlLocale) => {
35+
if (urlLocale) {
36+
if (urlLocale !== locale) {
37+
locale = urlLocale;
38+
}
39+
if (locale === DEFAULT_LOCALE) {
40+
const newUrl = req.url.replace(`/${DEFAULT_LOCALE}`, '') || '/';
41+
return res.redirect(307, newUrl);
42+
}
43+
} else if (locale !== DEFAULT_LOCALE) {
44+
let newUrl = `/${locale}${req.url}`;
45+
if (newUrl.endsWith('/') && newUrl.length > 1) {
46+
newUrl = newUrl.slice(0, -1);
47+
}
48+
return res.redirect(307, newUrl);
49+
}
50+
return false;
51+
};
52+
53+
const canSetCookie = (req) => {
54+
// 检查请求头中是否有 'cookie' 字段
55+
return req.headers.cookie !== undefined;
56+
};
57+
1458
async function startServer() {
1559
try {
1660
await app.prepare();
1761
const server = express();
1862
server.use(cookieParser());
63+
server.use(pino);
1964

20-
// 中间件处理语言选择和路由
2165
server.use((req, res, next) => {
22-
if (req.url.startsWith('/_next') || req.url.startsWith('/static')) {
23-
next();
24-
} else {
25-
let locale = req.cookies.locale;
26-
27-
// 解析 URL 中的语言设置
28-
const urlParts = req.path.split('/');
29-
const urlLocale = SUPPORTED_LOCALES.includes(urlParts[1])
30-
? urlParts[1]
31-
: null;
32-
33-
if (!locale) {
34-
// 如果没有 cookie,使用 URL 中的语言或浏览器偏好
35-
const browserLocale = req.acceptsLanguages(SUPPORTED_LOCALES);
36-
locale = urlLocale || browserLocale || FALLBACK_LOCALE;
37-
38-
// 如果浏览器语言不是中文,默认使用英语
39-
if (browserLocale && browserLocale !== 'zh') {
40-
locale = FALLBACK_LOCALE;
41-
}
42-
}
43-
44-
// 确保 locale 是支持的语言之一
45-
locale = SUPPORTED_LOCALES.includes(locale) ? locale : FALLBACK_LOCALE;
46-
if (urlLocale) {
47-
// URL 中有语言前缀
48-
if (urlLocale !== locale) {
49-
// URL 语言与 cookie 不匹配,更新 locale
50-
locale = urlLocale;
51-
}
52-
if (locale === DEFAULT_LOCALE) {
53-
// 默认语言不应该在 URL 中显示,重定向到无前缀的 URL
54-
const newUrl = req.url.replace(`/${DEFAULT_LOCALE}`, '') || '/';
55-
return res.redirect(307, newUrl);
56-
}
57-
} else if (locale !== DEFAULT_LOCALE) {
58-
// URL 中没有语言前缀,且不是默认语言,添加前缀并重定向
59-
let newUrl = `/${locale}${req.url}`;
60-
if (newUrl.endsWith('/')) {
61-
// 如果以 '/' 结尾,去掉末尾的 '/'
62-
newUrl = newUrl.slice(0, -1);
63-
}
64-
return res.redirect(307, newUrl);
65-
}
66-
67-
// 设置或更新 cookie
68-
res.cookie('locale', locale, {
69-
maxAge: 365 * 24 * 60 * 60 * 1000,
70-
});
66+
if (isStaticRoute(req.url)) {
67+
return next();
68+
}
7169

72-
req.locale = locale;
70+
const urlLocale = getLocaleFromUrl(req.path);
71+
let locale = determineLocale(req, urlLocale);
7372

74-
// // 处理尾部斜杠并重定向
75-
// if (req.url.length > 1 && req.path.endsWith('/')) {
76-
// const newUrl =
77-
// req.path.slice(0, -1) + req.params
78-
// return res.redirect(301, newUrl);
79-
// }
73+
if (handleRedirect(req, res, locale, urlLocale)) {
74+
return; // 如果发生重定向,立即返回
75+
}
8076

81-
next();
77+
// 检查响应头是否已经发送
78+
if (canSetCookie(req) && !res.headersSent) {
79+
res.cookie('locale', locale, { maxAge: 365 * 24 * 60 * 60 * 1000 });
8280
}
81+
req.locale = locale;
82+
next();
8383
});
8484

85-
// 处理所有其他请求
86-
server.all('*', (req, res) => {
87-
return handle(req, res);
88-
});
85+
server.all('*', (req, res) => handle(req, res));
8986

9087
server.listen(PORT, (err) => {
9188
if (err) throw err;
@@ -97,4 +94,4 @@ async function startServer() {
9794
}
9895
}
9996

100-
startServer();
97+
startServer();

0 commit comments

Comments
 (0)