You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter Firebase云函数代理CORS配置错误,请求头不被允许如何解决?

解决Firebase云函数代理的CORS配置问题

你的错误根源是向目标API发送请求时错误携带了CORS响应头,同时预检请求的配置也存在语法和内容错误。以下是具体修正步骤:

错误点分析

  1. OPTIONS预检响应错误:
    • Access-Control-Allow-Methods里混入了authorization(这是请求头字段,不是HTTP请求方法),导致预检校验不通过;
    • 代码中res.set('Access-Control-Allow-Origin','*'),多了一个逗号,属于语法错误。
  2. 向目标API发起请求的冗余头:
    Access-Control-Allow-Origin、Access-Control-Allow-Credentials这类头是服务端返回给前端的响应头,不是代理发给目标API的请求头,完全不需要携带。
  3. 响应处理逻辑错误:
    • 重复调用res.status()会导致响应异常;
    • fetch的响应对象没有直接的data属性,需要先调用json()或text()解析;
    • 代码里的response变量未定义,属于笔误。
  4. CORS中间件与手动OPTIONS处理冲突:
    已经手动处理了OPTIONS请求,再使用cors中间件会造成逻辑重复,建议二选一。

修正后的完整代码

const functions = require('firebase-functions');

exports.proxyAnafAPI = functions.https.onRequest((req, res) => {
    const apiUrl = 'https://webservicesp.anaf.ro/PlatitorTvaRest/api/v8/ws/tva' + req.url;

    // 处理OPTIONS预检请求
    if (req.method === 'OPTIONS') {
        res.set('Access-Control-Allow-Origin', '*');
        res.set('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, HEAD, OPTIONS');
        res.set('Access-Control-Allow-Headers', 'Content-Type, Authorization'); // 前端实际发送的自定义头都要列在这里
        res.set('Access-Control-Max-Age', '3600');
        return res.status(200).send('');
    }

    // 处理实际请求
    fetch(apiUrl, {
        method: req.method,
        headers: {
            'Content-Type': 'application/json',
            // 仅携带目标API需要的请求头,比如前端传了Authorization就转发
            ...(req.headers.authorization && { 'Authorization': req.headers.authorization })
        },
        body: req.method !== 'GET' ? JSON.stringify(req.body) : undefined // GET请求不要带body
    })
    .then(async apiRes => {
        // 给前端返回CORS响应头
        res.set('Access-Control-Allow-Origin', '*');
        res.set('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, HEAD, OPTIONS');
        res.set('Access-Control-Allow-Headers', 'Content-Type, Authorization');

        // 解析目标API响应并返回给前端
        const responseBody = await apiRes.json();
        return res.status(apiRes.status).json(responseBody);
    })
    .catch(error => {
        console.error('代理请求出错:', error);
        res.status(500).send('代理请求失败');
    });
});

关键说明

  • 仅在云函数返回给前端的响应中设置CORS头,向目标API发请求时只带目标API要求的头;
  • OPTIONS预检的Access-Control-Allow-Headers必须包含前端实际会发送的所有自定义请求头;
  • 避免手动处理OPTIONS和cors中间件同时使用,防止逻辑冲突;
  • fetch响应必须通过json()/text()方法解析后才能获取内容。

内容的提问来源于stack exchange,提问作者Roberto

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 14:30:57