2
2
const express = require ( 'express' ) ;
3
3
const next = require ( 'next' ) ;
4
4
const cookieParser = require ( 'cookie-parser' ) ;
5
+ const pino = require ( 'pino-http' ) ( ) ;
5
6
6
7
const app = next ( { dev : false } ) ;
7
8
const handle = app . getRequestHandler ( ) ;
@@ -11,81 +12,78 @@ const DEFAULT_LOCALE = 'zh';
11
12
const FALLBACK_LOCALE = 'en' ;
12
13
const SUPPORTED_LOCALES = [ 'zh' , 'en' ] ;
13
14
15
+ const isStaticRoute = ( url ) =>
16
+ url . startsWith ( '/_next' ) || url . startsWith ( '/static' ) ;
17
+
18
+ const getLocaleFromUrl = ( path ) => {
19
+ const urlParts = path . split ( '/' ) ;
20
+ return SUPPORTED_LOCALES . includes ( urlParts [ 1 ] ) ? urlParts [ 1 ] : null ;
21
+ } ;
22
+
23
+ const determineLocale = ( req , urlLocale ) => {
24
+ let locale = req . cookies . locale ;
25
+ if ( ! locale ) {
26
+ const browserLocale = req . acceptsLanguages ( SUPPORTED_LOCALES ) ;
27
+ locale = urlLocale || browserLocale || FALLBACK_LOCALE ;
28
+ if ( browserLocale && browserLocale !== 'zh' ) {
29
+ locale = FALLBACK_LOCALE ;
30
+ }
31
+ }
32
+ return SUPPORTED_LOCALES . includes ( locale ) ? locale : FALLBACK_LOCALE ;
33
+ } ;
34
+
35
+ const handleRedirect = ( req , res , locale , urlLocale ) => {
36
+ if ( urlLocale ) {
37
+ if ( urlLocale !== locale ) {
38
+ locale = urlLocale ;
39
+ }
40
+ if ( locale === DEFAULT_LOCALE ) {
41
+ const newUrl = req . url . replace ( `/${ DEFAULT_LOCALE } ` , '' ) || '/' ;
42
+ return res . redirect ( 307 , newUrl ) ;
43
+ }
44
+ } else if ( locale !== DEFAULT_LOCALE ) {
45
+ let newUrl = `/${ locale } ${ req . url } ` ;
46
+ if ( newUrl . endsWith ( '/' ) && newUrl . length > 1 ) {
47
+ newUrl = newUrl . slice ( 0 , - 1 ) ;
48
+ }
49
+ return res . redirect ( 307 , newUrl ) ;
50
+ }
51
+ return false ;
52
+ } ;
53
+
54
+ const canSetCookie = ( req ) => {
55
+ // 检查请求头中是否有 'cookie' 字段
56
+ return req . headers . cookie !== undefined ;
57
+ } ;
58
+
14
59
async function startServer ( ) {
15
60
try {
16
61
await app . prepare ( ) ;
17
62
const server = express ( ) ;
18
63
server . use ( cookieParser ( ) ) ;
64
+ server . use ( pino ) ;
19
65
20
- // 中间件处理语言选择和路由
21
66
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
- } ) ;
67
+ if ( isStaticRoute ( req . url ) ) {
68
+ return next ( ) ;
69
+ }
71
70
72
- req . locale = locale ;
71
+ const urlLocale = getLocaleFromUrl ( req . path ) ;
72
+ let locale = determineLocale ( req , urlLocale ) ;
73
73
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
- // }
74
+ if ( handleRedirect ( req , res , locale , urlLocale ) ) {
75
+ return ; // 如果发生重定向,立即返回
76
+ }
80
77
81
- next ( ) ;
78
+ // 检查响应头是否已经发送
79
+ if ( canSetCookie ( req ) && ! res . headersSent ) {
80
+ res . cookie ( 'locale' , locale , { maxAge : 365 * 24 * 60 * 60 * 1000 } ) ;
82
81
}
82
+ req . locale = locale ;
83
+ next ( ) ;
83
84
} ) ;
84
85
85
- // 处理所有其他请求
86
- server . all ( '*' , ( req , res ) => {
87
- return handle ( req , res ) ;
88
- } ) ;
86
+ server . all ( '*' , ( req , res ) => handle ( req , res ) ) ;
89
87
90
88
server . listen ( PORT , ( err ) => {
91
89
if ( err ) throw err ;
0 commit comments