后端内部化更改语言会话与系统
backend internalization change language session vs system
所以我的后端是用 nodejs 编写的,我正在使用 i18next 进行内部化。我也在前端使用它。前端的语言由域决定。例如es.domain.com 是西班牙语,ja.domain.com 是日语等
在后端,目标是通过域来源确定用户语言,并将响应语言更改为其来源。默认为英语。
我的问题是,
当我更改语言时,它会更改 API 默认语言还是那个请求会话语言?
即,如果用户 1 用日语发出请求需要 5 秒,而用户 2 用英语发出请求后用户 1 需要 1 秒。 user1 会不会意外收到英文回复?
抱歉,如果问题unclear/hard无法理解。请在下方评论,我会尝试改写。
const i18n = require('i18next');
const express = require('express');
const app = express();
const port = 3050;
const bodyParser = require('body-parser');
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
app.use(require('express-useragent').express());
// Internationalization
i18n.init({
resources: langResources,
lng: "en",
fallbackLng: "en",
interpolation: {
escapeValue: false
}
});
// Cors
app.use(function(req, res, next) {
// HERE's where I'll be detecting and changing the language
i18n.changeLanguage('ja');
console.log("i18n.t('test')",i18n.t('test',{count:1}));
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, auth-id, auth-token, x-csrf-token, _csrf");
res.header('Access-Control-Allow-Methods', 'PATCH, POST, GET, DELETE, OPTIONS');
next();
}); ```
我意识到我可以像这样快速测试一下。
我发送了两个请求。第一个睡眠时间为 5000 毫秒,ja
lang,而第二个睡眠时间为 150 毫秒,en
lang。
test: async function(req){
let user = req.query.user;
let lang = req.query.lang;
let time = req.query.time;
// console.log("test 0Ro-> i18n.t('test')",i18n.t('test',{count:1}));
i18n.changeLanguage(lang);
console.log("user 1Ro:",user,"lang 1Ro:",lang);
console.log("test 1Ro-> i18n.t('test')",i18n.t('test',{count:1}));
await sleep(time)
console.log("user 2Ro:",user,"lang 2Ro:",lang);
console.log("test 2Ro-> i18n.t('test')",i18n.t('test',{count:1}));
},
不幸的是,ja
语言用户以英语返回,这意味着更改语言不会更改会话语言,而是更改 api 语言。
这是问题的答案。但是我仍在寻找解决方案。
编辑:找不到 i18next 解决方案,所以我自己做了一个。如果您想使用它,就在这里。添加 express-session
您的项目。
app.js - 初始化
const {t} = require('./translations/i18n').i18n;
process.env.TZ = "Etc/GMT"
const express = require('express');
const session = require('express-session');
const app = express();
const port = 3050;
const bodyParser = require('body-parser');
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
app.use(require('express-useragent').express());
app.use(session({
secret: 'keyboard cat',
resave: false,
saveUninitialized: true,
cookie: { secure: true }
}))
// Cors
app.use(async function(req, res, next) {
let allowOrigins = [
'(.*my-domain\.com)',
];
if(Config.Env !== Environments.Production){
res.header("Access-Control-Allow-Origin", "*");
}else{
res.header("Access-Control-Allow-Origin", Config.FrontEnd.Url);
var origin = req.get('origin');
console.log("origin",origin);
for (let i = 0; i < allowOrigins.length; i++) {
const allowOrigin = allowOrigins[i];
if(origin.match(allowOrigin)){
res.header("Access-Control-Allow-Origin", origin);
}
}
}
// example vars
let user = req.query.user;
let lang = req.query.lang;
let time = req.query.time;
// set language on session
req.session.language = lang;
console.log("user 1Ro:",user,"lang 1Ro:",lang);
t(req,'test',{count: time});
await sleep(time);
console.log("user 2Ro:",user,"lang 2Ro:",lang);
t(req,'test',{count: time});
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, auth-id, auth-token, x-csrf-token, _csrf");
res.header('Access-Control-Allow-Methods', 'PATCH, POST, GET, DELETE, OPTIONS');
next();
});
all.js - 您的翻译放在这里。
// import translation objects here. then add to tranlations object
const convertToSingularLocale = (messages, locale ) => {
let singleLocale = Object.assign({}, messages)
for (let property in singleLocale) {
if (property === locale) {
return singleLocale[property]
} else if (typeof singleLocale[property] === 'object') {
singleLocale[property] = convertToSingularLocale(singleLocale[property], locale)
}
}
return singleLocale
}
const translations = {
general: {
languageAbbreviation: {
de: "de",
es: "es",
en: "en",
ja: "ja",
fr: "fr",
zh: "zh",
},
},
test:{
en: "TEST {{count}}",
ja: "テスト {{count}}",
}
}
const english = convertToSingularLocale(translations, 'en')
const japanese = convertToSingularLocale(translations, 'ja')
const langResources = {
en: english,
ja: japanese,
}
const availableLanguages = [
{ name: "English", nativeName:"English", code: "en" },
{ name: "Japanese", nativeName:"日本語", code: "ja" },
]
module.exports = {
langResources: langResources,
availableLanguages: availableLanguages,
}
i18n.js - 简单的翻译器
const defaultLang = "en";
const {langResources} = require('./all');
const translate = (req,str,args) => {
let validLang = false;
let lang = req.session.language;
for (var key in langResources) {
if(langResources.hasOwnProperty(key)) {
validLang = true;
break
}
}
if(!validLang){
lang = defaultLang;
}
const sourceLang = langResources[lang];
var keys = str.split(".");
let source = sourceLang;
for (let i = 0; i < keys.length; i++) {
const key = keys[i];
source = source[key];
}
let text = source;
for (var key in args) {
if(args.hasOwnProperty(key)) {
text = text.replace("{{"+key+"}}", args[key]);
}
}
return text;
}
const i18n = {
translate: translate,
t: translate,
}
module.exports = {
i18n: i18n,
}
所以我的后端是用 nodejs 编写的,我正在使用 i18next 进行内部化。我也在前端使用它。前端的语言由域决定。例如es.domain.com 是西班牙语,ja.domain.com 是日语等
在后端,目标是通过域来源确定用户语言,并将响应语言更改为其来源。默认为英语。
我的问题是,
当我更改语言时,它会更改 API 默认语言还是那个请求会话语言? 即,如果用户 1 用日语发出请求需要 5 秒,而用户 2 用英语发出请求后用户 1 需要 1 秒。 user1 会不会意外收到英文回复?
抱歉,如果问题unclear/hard无法理解。请在下方评论,我会尝试改写。
const i18n = require('i18next');
const express = require('express');
const app = express();
const port = 3050;
const bodyParser = require('body-parser');
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
app.use(require('express-useragent').express());
// Internationalization
i18n.init({
resources: langResources,
lng: "en",
fallbackLng: "en",
interpolation: {
escapeValue: false
}
});
// Cors
app.use(function(req, res, next) {
// HERE's where I'll be detecting and changing the language
i18n.changeLanguage('ja');
console.log("i18n.t('test')",i18n.t('test',{count:1}));
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, auth-id, auth-token, x-csrf-token, _csrf");
res.header('Access-Control-Allow-Methods', 'PATCH, POST, GET, DELETE, OPTIONS');
next();
}); ```
我意识到我可以像这样快速测试一下。
我发送了两个请求。第一个睡眠时间为 5000 毫秒,ja
lang,而第二个睡眠时间为 150 毫秒,en
lang。
test: async function(req){
let user = req.query.user;
let lang = req.query.lang;
let time = req.query.time;
// console.log("test 0Ro-> i18n.t('test')",i18n.t('test',{count:1}));
i18n.changeLanguage(lang);
console.log("user 1Ro:",user,"lang 1Ro:",lang);
console.log("test 1Ro-> i18n.t('test')",i18n.t('test',{count:1}));
await sleep(time)
console.log("user 2Ro:",user,"lang 2Ro:",lang);
console.log("test 2Ro-> i18n.t('test')",i18n.t('test',{count:1}));
},
不幸的是,ja
语言用户以英语返回,这意味着更改语言不会更改会话语言,而是更改 api 语言。
这是问题的答案。但是我仍在寻找解决方案。
编辑:找不到 i18next 解决方案,所以我自己做了一个。如果您想使用它,就在这里。添加 express-session
您的项目。
app.js - 初始化
const {t} = require('./translations/i18n').i18n;
process.env.TZ = "Etc/GMT"
const express = require('express');
const session = require('express-session');
const app = express();
const port = 3050;
const bodyParser = require('body-parser');
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
app.use(require('express-useragent').express());
app.use(session({
secret: 'keyboard cat',
resave: false,
saveUninitialized: true,
cookie: { secure: true }
}))
// Cors
app.use(async function(req, res, next) {
let allowOrigins = [
'(.*my-domain\.com)',
];
if(Config.Env !== Environments.Production){
res.header("Access-Control-Allow-Origin", "*");
}else{
res.header("Access-Control-Allow-Origin", Config.FrontEnd.Url);
var origin = req.get('origin');
console.log("origin",origin);
for (let i = 0; i < allowOrigins.length; i++) {
const allowOrigin = allowOrigins[i];
if(origin.match(allowOrigin)){
res.header("Access-Control-Allow-Origin", origin);
}
}
}
// example vars
let user = req.query.user;
let lang = req.query.lang;
let time = req.query.time;
// set language on session
req.session.language = lang;
console.log("user 1Ro:",user,"lang 1Ro:",lang);
t(req,'test',{count: time});
await sleep(time);
console.log("user 2Ro:",user,"lang 2Ro:",lang);
t(req,'test',{count: time});
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, auth-id, auth-token, x-csrf-token, _csrf");
res.header('Access-Control-Allow-Methods', 'PATCH, POST, GET, DELETE, OPTIONS');
next();
});
all.js - 您的翻译放在这里。
// import translation objects here. then add to tranlations object
const convertToSingularLocale = (messages, locale ) => {
let singleLocale = Object.assign({}, messages)
for (let property in singleLocale) {
if (property === locale) {
return singleLocale[property]
} else if (typeof singleLocale[property] === 'object') {
singleLocale[property] = convertToSingularLocale(singleLocale[property], locale)
}
}
return singleLocale
}
const translations = {
general: {
languageAbbreviation: {
de: "de",
es: "es",
en: "en",
ja: "ja",
fr: "fr",
zh: "zh",
},
},
test:{
en: "TEST {{count}}",
ja: "テスト {{count}}",
}
}
const english = convertToSingularLocale(translations, 'en')
const japanese = convertToSingularLocale(translations, 'ja')
const langResources = {
en: english,
ja: japanese,
}
const availableLanguages = [
{ name: "English", nativeName:"English", code: "en" },
{ name: "Japanese", nativeName:"日本語", code: "ja" },
]
module.exports = {
langResources: langResources,
availableLanguages: availableLanguages,
}
i18n.js - 简单的翻译器
const defaultLang = "en";
const {langResources} = require('./all');
const translate = (req,str,args) => {
let validLang = false;
let lang = req.session.language;
for (var key in langResources) {
if(langResources.hasOwnProperty(key)) {
validLang = true;
break
}
}
if(!validLang){
lang = defaultLang;
}
const sourceLang = langResources[lang];
var keys = str.split(".");
let source = sourceLang;
for (let i = 0; i < keys.length; i++) {
const key = keys[i];
source = source[key];
}
let text = source;
for (var key in args) {
if(args.hasOwnProperty(key)) {
text = text.replace("{{"+key+"}}", args[key]);
}
}
return text;
}
const i18n = {
translate: translate,
t: translate,
}
module.exports = {
i18n: i18n,
}