我们尝试在 Vercel 中部署的 Next.js
14.2.13
中实现服务器操作,但每 4/5 次调用我们都会收到间歇性的 405 状态代码
这是函数
'use server';
import {
CreateNoteFormDataSchema,
NoteFormInputs,
} from '@/src/features/Notes/CreateNoteInDeck/NoteForm/createNoteSchema';
import axios from 'axios';
import { BASE_URL } from '@/src/app/api/Api';
import { getServerSession } from 'next-auth';
import { authOptions } from '@/src/app/api/auth/[...nextauth]/authOptions';
import { getHeaders } from '@/src/app/api/getHeaders';
import { sanitizeHTML } from '@/src/app/api/utils/sanitizeHTML';
import { FontTypes } from '@/src/features/Notes/utils/FontFamilyConfig';
type CreateNoteReqBody = {
title: string;
body: string;
deckId?: number | null;
tags: string[];
pattern: string | null;
backgroundColor: string | null;
fontFamily: string | null;
visibility: 'public' | 'private' | 'friends';
};
type CreateNoteResBody = {
noteId: string;
deckId: number | null;
title: string;
body: string;
bodySummary: string;
tags: string[];
pattern: string | null;
backgroundColor: string | null;
fontFamily: string | null;
visibility: 'public' | 'private' | 'friends';
updatedAt: string;
};
export type CreateNoteServerActionState = {
success: boolean;
error: string | null;
data: CreateNoteResBody | null;
};
export async function _createNoteServerAction(data: NoteFormInputs): Promise<CreateNoteServerActionState> {
try {
const parsedData = CreateNoteFormDataSchema.parse({
deckId: data.deckId,
backgroundColor: data.backgroundColor,
fontType: data.fontType,
visibility: data.visibility,
title: sanitizeHTML(data.title),
body: sanitizeHTML(data.body),
tags: data.tags?.map((tag) => sanitizeHTML(tag)) || [],
});
const validatedData: CreateNoteReqBody = {
deckId: parsedData.deckId || null,
title: parsedData.title,
body: parsedData.body,
backgroundColor: parsedData.backgroundColor || null,
visibility: parsedData.visibility,
fontFamily: data.fontType || FontTypes[0],
pattern: null,
tags: parsedData.tags || [],
};
const session = await getServerSession(authOptions);
const config = getHeaders(session?.accessToken);
const response = await axios.post<CreateNoteResBody>(`${EXTERNAL_API_BASE_URL}/note`, validatedData, config);
return { success: true, data: response.data, error: null };
} catch (error) {
console.error('createNoteServerAction', error);
return { success: false, error: 'Something went wrong', data: null };
}
}
从这里调用:
const {
register,
handleSubmit,
control,
formState: { errors },
watch,
setValue,
} = useForm<NoteFormInputs>({
defaultValues: {
deckId,
title: defaultNote?.title || '',
body: defaultNote?.body || '',
backgroundColor: defaultNote?.backgroundColor || '',
pattern: defaultNote?.pattern || '',
fontType: defaultNote?.font.name || FontTypes[0],
visibility: defaultNote?.visibility || 'public',
tags: defaultNote?.tags || [],
},
resolver: zodResolver(CreateNoteFormDataSchema),
});
// ....
const onSubmit: SubmitHandler<NoteFormInputs> = useCallback(
(data) => {
startTransition(async () => {
if (defaultNote?.id) {
const editResult = await _editNoteServerAction(defaultNote.id, data);
if (editResult.success && editResult.data) {
BBToast.success('Note updated');
return;
}
BBToast.error('Failed to update note');
return;
}
const result = await _createNoteServerAction(data);
if (result.success && result.data) {
BBToast.success('Note created');
return router.replace(`${pathName}/../${result.data.noteId}`);
}
BBToast.error('Failed to create note');
return;
});
},
[defaultNote?.id, pathName, router],
);
// ....
<form onSubmit={handleSubmit(onSubmit)} className="p-4 h-full">
Vercel 的原木是
500
在客户端 chrome 控制台上有一个
405
任何有关为什么会发生这种情况的帮助、想法或解释,我们将不胜感激!
就我而言,这是由于标题中设置了错误的
Content-Security-Policy
。
就我而言,它位于
vercel.json
文件中。
这是我更新的配置:
{
"key": "Content-Security-Policy",
"value": "default-src 'self'; script-src 'self' THIRD_PARTY_API_URL_1 THIRD_PARTY_API_URL_2; style-src 'self' 'unsafe-inline'; img-src IMAGE_PROVIDER_URL 'self' data:; connect-src 'self' BACKEND_URL THIRD_PARTY_API_URL; frame-src 'self' EXTERNAL_I_FRAME_URL"
}
您在哪里更新
...API_URL...
并使用 url(接受通配符)