Next.js初始化和一些配置
我的版本是@14.2.3
初始化
配置
路径别名
跨域问题
- 改为服务端组件
把发起跨域请求的组件顶层的'use client'
删掉 - 使用后端接口转发
在Next.js自定义一个接口,前端改为调用此接口:
// 比如在api/request1.ts
export async function GET() {
const res = await fetch('https://...')
const data = await res.text()
return Response.json({ data })
}
// 在目标组件调用它:
const fetchArticleList = async () => {
const response = await fetch("http://localhost:3000/api/erquest1");
const data = await response.json()
}
fetchArticleList()
- 使用
rewrites
配置项
修改next.config.mjs
,代码如下:
/** @type {import('next').NextConfig} */
const nextConfig = {
async rewrites() {
return [
{
source: '/api/request1',
destination: 'https://...', // 真实地址
}
]
}
};
export default nextConfig;
- 使用
headers
配置项
修改next.config.mjs
,代码如下:
/** @type {import('next').NextConfig} */
const nextConfig = {
async headers() {
return [
{
source: "/api/:path*",
headers: [
{
key: "Access-Control-Allow-Origin",
value: "*",
},
{
key: "Access-Control-Allow-Methods",
value: "GET, POST, PUT, DELETE, OPTIONS",
},
{
key: "Access-Control-Allow-Headers",
value: "Content-Type, Authorization",
},
],
},
];
}
};
export default nextConfig;
- 使用中间件处理
比如我们要发起请求:
import { NextResponse } from 'next/server'
export async function GET() {
const data = { success: true, data: { name: "yayu"}}
return NextResponse.json(data)
}
在根目录新建middleware.js:
import { NextResponse } from 'next/server'
const allowedOrigins = ['https://...'] // 真实地址
const corsOptions = {
'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, OPTIONS',
'Access-Control-Allow-Headers': 'Content-Type, Authorization',
}
export function middleware(request) {
// 检查请求的 origin 属性
const origin = request.headers.get('origin') ?? ''
const isAllowedOrigin = allowedOrigins.includes(origin)
// 处理预检 OPTIONS 请求
const isPreflight = request.method === 'OPTIONS'
if (isPreflight) {
const preflightHeaders = {
...(isAllowedOrigin && { 'Access-Control-Allow-Origin': origin }),
...corsOptions,
}
return NextResponse.json({}, { headers: preflightHeaders })
}
// 处理普通请求
const response = NextResponse.next()
if (isAllowedOrigin) {
response.headers.set('Access-Control-Allow-Origin', origin)
}
Object.entries(corsOptions).forEach(([key, value]) => {
response.headers.set(key, value)
})
return response
}
export const config = {
matcher: '/api/:path*',
}
- 其他处理方式
如果上面的办法还是有跨域问题,可能是当你发送请求(如post)时,会先发送一个预检请求,而你的后端部分没有处理这段逻辑可能活导致报错,如下面的请求处理:
// 处理请求函数
const handlerRequest = async (req: Request): Promise<Response> => {
const data = (await req.json()) as Data
return NextResponse.json(
code: 200,
msg: 'success'
)
}
如果是前端发送预检请求,走到handlerRequest
函数,由于OPTIONS
请求没有Body
,代码运行到await req.json()
时,就会报错。于是浏览器认为OPTIONS请求
没有返回status 200
,因此强行认为你的接口不支持跨域。
图片跨域问题
如果你使用其他域名的图片时会报错:
<Image width={100} height={100} src="https://image.baidu.com/search/..." alt="baiduImage" className={styles.img} />
报错里面有个链接,有解释报错原因,解决办法:
12.3.0之后的版本:
module.exports = {
images: {
remotePatterns: [
{
protocol: 'https',
hostname: 'image.baidu.com',
port: '',
pathname: '/search/**',
},
],
},
}
12.3.0之前的版本:
module.exports = {
images: {
domains: ['image.baidu.com'],
},
}