#node.js #internationalization #i18next
#node.js #интернационализация #i18next
Вопрос:
Итак, мой бэкэнд написан на nodejs, и я использую i18next для интернализации. Я также использую его на интерфейсе. Язык интерфейса определяется доменом. например es.domain.com является испанским и ja.domain.com является японским и т.д.
На серверной части цель состоит в том, чтобы определить язык пользователей через источник домена и изменить язык ответа на их происхождение. По умолчанию будет английский.
Мой вопрос,
Когда я меняю язык, изменится ли язык API по умолчанию или язык сеанса запроса? то есть, если пользователь1 делает запрос на японском языке, который занимает 5 секунд, в то время как пользователь2 делает запрос на английском языке, который занимает 1 секунду сразу после пользователя 1. Пользователь1 случайно получит ответ на английском языке?
Извините, если вопрос неясен / труден для понимания. Пожалуйста, прокомментируйте ниже, и я постараюсь перефразировать это.
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();
}); ```
Ответ №1:
Я понял, что могу просто сделать быстрый тест этого вот так.
Я отправил два запроса. У первого было время ожидания 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,
}