【问题标题】:Firebase hosting Access-Control-Allow-Origin for app engine URLFirebase 托管应用引擎 URL 的 Access-Control-Allow-Origin
【发布时间】:2017-06-24 23:12:40
【问题描述】:

我在 Firebase 托管上托管一个单页应用,我需要允许跨域请求到应用引擎。应用托管在 project-id.firebaseapp.com 上,应用引擎服务托管在 project-id.appspot.com 上。我红色了deployment documentation,没有示例如何为 URL 添加 Access-Control-Allow-Origin 标头。

这是我的 firebase.json 的样子:

{
  "database": {
    "rules": "database.rules.json"
  },
  "hosting": {
    "public": "public",
    "redirects": [
      {
        "source": "/server/:rest*",
        "destination": "https://app-id.appspot.com/:rest*",
        "type": 301
      }
    ],
    "rewrites": [
      {
        "source": "/views/**",
        "destination": "/views/**"
      },
      {
        "source": "**",
        "destination": "/index.html"
      }
    ],
    "headers": [ {
      "source" : "https://app-id.appspot.com/registration/generate",
      "headers" : [ {
        "key" : "Access-Control-Allow-Origin",
        "value" : "*"
      } ]
    } ]
  }
}

我尝试使用 gsutils 设置 CORS,但也没有用:

这是我的 cors.json

[
    {
        "maxAgeSeconds": 3600, 
        "method": ["GET", "POST"], 
        "origin": ["https://project-id.appspot.com/"]
    }
]

提前致谢

解决方案:

如果您只想在静态文件上允许 CORS,那么在 app.yaml 中设置 Access-Control-Allow-Origin 标头就足够了。此标头不允许在动态请求的 app.yaml 中,因此您必须以编程方式添加它。

如果您的请求很简单,则以下代码有效:

@Override
public void doPost(HttpServletRequest req, HttpServletResponse resp) 
    resp.addHeader("Access-Control-Allow-Origin", "*");
    resp.addHeader("Content-Type", "text/csv");
    resp.getWriter().append("Response");

}

但是,如果您的请求是预先发送的,则必须覆盖 doOptions 方法并添加适当的标头:

@Override
protected void doOptions(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    resp.addHeader("Access-Control-Allow-Origin", "*");
    resp.addHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS");
    resp.addHeader("Access-Control-Allow-Headers", "Content-Type");
}

@Override
public void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException {
    resp.addHeader("Access-Control-Allow-Origin", "*");
    resp.addHeader("Content-Type", "text/csv");
    resp.getWriter().append("Response");
}

Here 是一个有用的图表,它阐明了服务器上的 CORS 实现:

【问题讨论】:

    标签: firebase firebase-hosting


    【解决方案1】:

    您的 firebase.json 不控制 appspot.com 文件,也不能用于修改您的应用引擎服务的标头。在这里,您尝试在https://app-id.appspot.com/registration/generate 上设置Access-Control-Allow-Origin。这是行不通的,因为这不是 Firebase Hosting 托管的页面。

    相反,向 Firebase 页面添加标头的方法是将其放在 firebase.json 中,如下所示:

    "headers": [ {
      "source" : "index.html",
      "headers" : [ {
        "key" : "Access-Control-Allow-Origin",
        "value" : "*"
      } ]
    } ]
    

    但这无助于解决 CORS 问题,因为它需要就位 on the returned resource

    看来你可以根据this doc把它放到handlers下的app.yaml中。

    handlers:
    - url: /.*
      http_headers:
        Access-Control-Allow-Origin: http://mygame.appspot.com
    

    此外,您可以通过编程方式添加它。正如 enable-cors.org 上所解释的,这里有一些脚本实现:

    对于 Google App Engine 中基于 Python 的应用程序,可以使用self.response.headers.add_header() 方法,例如:

    class CORSEnabledHandler(webapp.RequestHandler):
      def get(self):
        self.response.headers.add_header("Access-Control-Allow-Origin", "*")
        self.response.headers['Content-Type'] = 'text/csv'
        self.response.out.write(self.dump_csv())
    

    对于基于 Java 的应用程序,请使用 resp.addHeader()

    public void doGet(HttpServletRequest req, HttpServletResponse resp) {
      resp.addHeader("Access-Control-Allow-Origin", "*");
      resp.addHeader("Content-Type", "text/csv");
      resp.getWriter().append(csvString);
    }
    

    对于基于 Go 的应用程序,请使用 w.Header().Add()

    func doGet(w http.ResponseWriter, r *http.Request) {
      w.Header().Add("Access-Control-Allow-Origin", "*")
      w.Header().Add("Content-Type", "text/csv")
      fmt.Fprintf(w, csvData)
    }
    

    【讨论】:

      猜你喜欢
      • 2011-11-05
      • 2017-06-15
      • 2016-09-30
      • 2015-06-17
      • 1970-01-01
      • 2017-12-29
      • 1970-01-01
      • 2019-02-07
      • 1970-01-01
      相关资源
      最近更新 更多