Next实现国际化,接口反向代理,冲突了

作者在使用Next.js进行项目开发时,尝试集成next-intl进行国际化处理,同时遇到跨域问题,通过添加反向代理解决,但两者结合时出现404错误。解决方法是调整next-intl的配置以忽略特定路径如/capi。
摘要由CSDN通过智能技术生成

最近在写next的项目,用到了国际化,使用了 react-i18next 但是感觉很费劲,配置起来很麻烦,所以换了一种方式,那就是:next-intl

发现还不错,后来要做接口,发现跨域,然后增加反向代理,则两者出现了冲突

国际化

第一步,需要安装

npm install next-intl

第二步,配置

import createNextIntlPlugin from 'next-intl/plugin';
const withNextIntl = createNextIntlPlugin();

/** @type {import('next').NextConfig} */
const nextConfig = {};
export default withNextIntl(nextConfig)

src 目录下创建 i18n-config.ts i18n.ts middleware.ts 文件 与 messages 目录

export const i18n = {
    defaultLocale: "en",
    locales: ["en", "zh"],
} as const;
export const locales = i18n.locales;
export const defaultLocale = i18n.defaultLocale;
import { notFound } from "next/navigation";
import { getRequestConfig } from 'next-intl/server';
import { locales } from '@/i18n-config'

export default getRequestConfig(async ({ locale }: any) => {
    if (!locales.includes(locale)) notFound();

    console.log(locale)
    return {
        messages: (await import(`./messages/${locale}.json`)).default
    };
});
import createMiddleware from 'next-intl/middleware';
import { locales, defaultLocale } from '@/i18n-config';

export default createMiddleware({
    locales,
    defaultLocale,
    // 默认语言不重定向
    localePrefix: 'as-needed'
});

export const config = {
    matcher: ['/((?!api|_next|_vercel|.*\\..*).*)']
};

在这里插入图片描述

messages目录结构

{
    "head": {
        "Login":"Login"
    }
}

项目结构:

在这里插入图片描述

要把以前写的页面 放到 [locale] 中,这样路由则会走 /语言/index

第三步:使用

服务端:

import {useTranslations} from 'next-intl';
export default function Page() {
  const t = useTranslations('Head');
  return (
    <div className="note--empty-state">
      <span className="note-text--empty-state">
        {t('login')}
      </span>
    </div>
  )
}
import {getTranslations} from 'next-intl/server';

export default async function Page() {
  const t = await getTranslations('Head');
  return (
    <div className="note--empty-state">
      <span className="note-text--empty-state">
        {t('initText')}
      </span>
    </div>
  )
}

客户端:

import {useTranslations} from 'next-intl';
export default function Sidebar() {
  const t = useTranslations('Head');
  return (
    <>
      <section className="col sidebar">
        <section className="sidebar-menu" role="menubar">
          <SidebarSearchField search={t('search')} />
          <EditButton noteId={null}>{t('new')}</EditButton>
        </section>
      </section>
    </>
  )
}

如果不能如期使用则需要在父组件增加 NextIntlClientProvider 传递message参数 完成该结果

// 部分代码省略
import { NextIntlClientProvider, useMessages } from "next-intl";

// 渲染部分

const RootLayout = ({
  children,
  params,
}: Readonly<{
  children: React.ReactNode;
  params: { lang: Locale };
}>) => {
  const messages = useMessages();
  return (
    <html lang={params.lang}>
      <body className={inter.className}>
        <Provider>
          <NextIntlClientProvider messages={{ head: messages.head }}>
            <LayoutHead ></LayoutHead>
            {children}
            <LayoutFoot></LayoutFoot>
          </NextIntlClientProvider>
        </Provider>
      </body>
    </html>
  );
}

接口反向代理

为了配置反向代理,我以为需要配置 proxy 才可以,next 则不需要,只需要更改重写规则即可。

/** @type {import('next').NextConfig} */
const nextConfig = {
    async rewrites() {
        return {
            fallback: [
                {
                    source: '/capi/:path*',
                    destination: `http://127.0.0.1:3000/:path*`,
                },
            ],
        }
    },
};
export default nextConfig;
import axios from 'axios'

let baseURL: string = "";
baseURL = "/capi"
// 拦截器
axios.interceptors.response.use((response) => {
    return response
}, (error) => {
    return Promise.reject(error)
})
axios.interceptors.request.use((config) => {
    console.log(config)
    config.headers['Accept'] = 'application/vnd.dpexpo.v1+json'
    config.baseURL = baseURL;
    config.timeout = 10000
    return config;
}, (error) => {
    return Promise.reject(error)
})

// axios的get请求
export function getAxios({
    url,
    params = {}
}: { url: string, params: any }) {
    return new Promise((resolve, reject) => {
        axios.get(url, {
            params,
        }).then(res => {
            resolve(res.data)
        }).catch(err => {
            console.log(err, '1')
            reject(err)
        })
    })
}

// axios的post请求
export function postAxios({
    url,
    data
}: any) {
    return new Promise((resolve, reject) => {
        axios({
            url,
            method: 'post',
            data
        }).then(res => {
            resolve(res.data)
        }).catch(err => {
            reject(err)
        })
    })
}

export default axios

import { getAxios, postAxios } from '@/utils/axios'

export const getArticle = (params: any) => {
    return getAxios({
        url: "/getArticleList",
        params
    })
}

请求 /getArticleList 则对应请求的是 /capi/getArticleList

重写规则,则重定向到 [http://127.0.0.1:3000](http://127.0.0.1:3000)/getArticleList

问题来了

现在都可以实现,但是两者结合,则会报错,请求404

那怎么办?

很简单

import createMiddleware from 'next-intl/middleware';
import { locales, defaultLocale } from '@/i18n-config';

export default createMiddleware({
    locales,
    defaultLocale,
    // 默认语言不重定向
    localePrefix: 'as-needed'
});

export const config = {
   //注意观察这一样的不同 多了capi 忽略了capi的路由
    matcher: ['/((?!api|_next|_vercel|capi|.*\\..*).*)']
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值