Next.js初始化和一些配置
- Next.js初始化和一些配置
- 初始化
- 配置
- 路径别名
- 跨域问题
- 图片跨域问题
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 Datareturn 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'],},
}