代码之家  ›  专栏  ›  技术社区  ›  Jake

为firebase可调用函数避免cors预飞

  •  -2
  • Jake  · 技术社区  · 5 年前

    我有一个 Firebase Callable Cloud Function 我在浏览器的javascript应用程序中调用它。

    因为请求主机是…cloudfunctions.net而不是我的应用程序域,所以在真正的post请求之前会产生cors preflight options请求。

    如果这是 function with http trigger 通过在宿主配置中将我的函数指定为重写并将请求发送到托管我的应用程序的同一个域,我可以避免飞行前花费的额外时间。

    有没有什么方法可以避免使用firebase可调用云函数的这种飞行前准备?也许有一种方法可以通过firebase托管代理请求,比如 you can with http Cloud Functions

    1 回复  |  直到 5 年前
        1
  •  2
  •   Jake    5 年前

    在对firebase文档和js sdk源代码进行了梳理之后,我决定如果不使用/重写私有api,这是不可能的。

    我使用的解决方案是复制 JS SDK code 但是指定一个url via Firebase Hosting 所以它和我的应用程序在同一个域上。

    相同的云功能,相同的应用程序代码,没有CORS飞行前


    1. 创建一个普通的firebase可调用云函数
    2. 将重写添加到 firebase.json
    {
     ...
     "hosting": {
       ...
       "rewrites": [
          {
            "source": "myFunction",
            "function": "myFunction"
          }
       ]
     }
    }
    
    1. 而不是叫它 firebase.functions().httpsCallable('myFunction') 向您自己的新url发送post请求
    const token = await firebase.auth().currentUser.getIdToken()
    const response = await fetch(
      'https://myapp.web.app/myFunction',
      {
        headers: {
          'Content-Type': 'application/json',
          Authorization: 'Bearer ' + token
        },
        method: 'post',
        body: JSON.stringify({ data })
      }
    )
    

    现在url在您的域中,所以没有cors问题

        2
  •  0
  •   micksatana    5 年前

    如果你用的是 region 在服务器端,还要确保在客户端指定区域。希望能帮上忙。

    firebase函数

    exports.status = functions
      .runWith({
        memory: '128MB',
        timeoutSeconds: 15
      })
      .region('asia-east2')
      .https.onCall((data, context) => {
        return { message: 'OK' };
      });
    

    网络客户端

    let functions = firebase.functions('asia-east2');
    let status = functions.httpsCallable('status');
    status({}).then(res => console.log(res));
    
        3
  •  -1
  •   Tony Yip    5 年前

    由于安全原因,无法跳到预先点燃的请求

    参考文献: https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS#Preflighted_requests

    当满足以下所有条件时,预燃请求将跳过:

    • 唯一允许的方法是:
      • 得到
    • 除了由用户代理自动设置的头(例如,连接、用户代理或在fetch规范中定义为禁止的头名称的任何其他头)之外,唯一允许手动设置的头是fetch spec定义为cors safelist请求头的头,这些头是:
      • 接受
      • 接受语言
      • 内容语言
      • 内容类型(但请注意下面的附加要求)
      • DPR
      • 下行链路
      • 保存数据
      • 视窗宽度
      • 宽度
    • 内容类型头的唯一允许值是:
      • 应用程序/x-www-form-urlencoded
      • 多部分/表单数据
      • 文本/平原
    • 没有在请求中使用的任何xmlhttprequest upload对象上注册事件侦听器;这些侦听器是使用xmlhttprequest.upload属性访问的。
    • 请求中未使用ReadableStream对象。