使用Supabase边缘函数调用Eventbrite API时POST返回GET响应问题
问题:POST请求Eventbrite创建场地接口却返回GET结果(Supabase边缘函数)
因CORS限制,无法在React客户端直接调用Eventbrite API,改用Supabase边缘函数发起请求。调用Eventbrite创建场地接口时,已明确指定POST方法,但返回的却是场地列表(GET请求的结果),请求还被重定向,无法完成场地创建。
React客户端调用Supabase边缘函数代码
export const createVenue = async (organizationId, venueData) => { console.log(venueData) const { data, error } = await supabase.functions.invoke("createVenue", { body: JSON.stringify({ organizationId, venueData }), }); if (error) { console.error("Error creating venue:", error.message); } else { console.log(data) return data; } };
venueData日志内容
{ "name": "ASDF, Jalan Boulevard Bukit Gading Raya, West Kelapa Gading, North Jakarta City, Jakarta, Indonesia" }
Supabase边缘函数createVenue代码
const corsHeaders = { "Access-Control-Allow-Origin": "*", "Access-Control-Allow-Headers": "authorization, x-client-info, apikey, content-type", }; Deno.serve(async (req) => { if (req.method === "OPTIONS") { return new Response("ok", { headers: corsHeaders }); } const eventbriteApiKey = API_KEY; if (!eventbriteApiKey) { return new Response("Unauthorized, no Eventbrite Key", { status: 401 }); } try { const { organizationId, venueData } = await req.json(); const response = await fetch( `https://www.eventbriteapi.com/v3/organizations/${organizationId}/venues`, { method: "POST", headers: { "Content-Type": "application/json", Authorization: `Bearer ${eventbriteApiKey}`, }, body: JSON.stringify({ venue: venueData }), } ); console.log(response); if (!response.ok) { const responseBody = await response.json(); return new Response(JSON.stringify(responseBody), { status: response.status, headers: { ...corsHeaders, "Content-Type": "application/json" }, }); } const responseBody = await response.json(); console.log(responseBody); return new Response(JSON.stringify({ success: true }), { status: 200, headers: { ...corsHeaders, "Content-Type": "application/json" }, }); } catch (error) { return new Response(JSON.stringify({ error: error.message }), { status: 500, headers: { ...corsHeaders, "Content-Type": "application/json" }, }); } });
边缘函数日志信息
Response日志
[Info] Response { body: ReadableStream { locked: false }, ...(省略部分日志) redirected: true, status: 200, url: "https://www.eventbriteapi.com/v3/organizations/2069088507983/venues/" }
ResponseBody日志
[Info] { pagination: { ... }, venues: [ ... ] }
解决方案
问题根源是Eventbrite API的URL重定向规则:当请求的URL末尾没有斜杠时,Eventbrite会返回重定向到带斜杠的URL;而fetch默认会在重定向时把POST请求转为GET请求(符合HTTP 3xx重定向的处理规范),导致最终执行的是GET请求,返回场地列表。
修复步骤
修改请求URL,添加末尾斜杠
将边缘函数中的请求URL从:`https://www.eventbriteapi.com/v3/organizations/${organizationId}/venues`改为:
`https://www.eventbriteapi.com/v3/organizations/${organizationId}/venues/`这样可以避免触发重定向,POST请求会直接被接口处理。
验证请求体格式
确保venueData包含Eventbrite API要求的必填字段(name已提供,若需要其他字段可参考官方规范补充),请求体{ venue: venueData }的格式符合接口要求。调整返回逻辑(可选)
修复后,接口会返回创建成功的场地数据,可修改边缘函数的返回逻辑,把实际的场地数据返回给客户端:return new Response(JSON.stringify({ success: true, venue: responseBody }), { status: 200, headers: { ...corsHeaders, "Content-Type": "application/json" }, });
修改后重新部署边缘函数,即可正常通过POST请求创建场地。
内容的提问来源于stack exchange,提问作者nearhanfarhan
相关产品推荐
相关产品推荐

