Reputation: 722
I am hosting a single page app on Firebase hosting and I need to allow cross domain request to app engine. App is hosted at project-id.firebaseapp.com and the app engine service on project-id.appspot.com. I red the deployment documentation and there is no example how to add Access-Control-Allow-Origin header for URL.
Here is what my firebase.json looks like:
{
"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" : "*"
} ]
} ]
}
}
I've tried to set the CORS using gsutils but it didn't help as well:
Here is my cors.json
[
{
"maxAgeSeconds": 3600,
"method": ["GET", "POST"],
"origin": ["https://project-id.appspot.com/"]
}
]
Thanks in advance
SOLUTION:
If all you want is to allow CORS on static files then setting the Access-Control-Allow-Origin header in app.yaml is enough. This header is not allowed to be in app.yaml on dynamic requests so you'll have to add it programatically.
If your request is a simple one then the following code works:
@Override
public void doPost(HttpServletRequest req, HttpServletResponse resp)
resp.addHeader("Access-Control-Allow-Origin", "*");
resp.addHeader("Content-Type", "text/csv");
resp.getWriter().append("Response");
}
However if your request is pre-flighted you'll have to override the doOptions method and add the appropriate headers:
@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 is a helpful diagram which clarifies CORS implementation on server:
Upvotes: 11
Views: 20585
Reputation: 40582
Your firebase.json does not control appspot.com files and can't be used to modify headers from your app engine service. Here, you've tried to set Access-Control-Allow-Origin
on https://app-id.appspot.com/registration/generate
. That's not going to work since that's not a page hosted at Firebase Hosting.
Instead, the way you would add a header to a Firebase page would be to put it in the firebase.json like so:
"headers": [ {
"source" : "index.html",
"headers" : [ {
"key" : "Access-Control-Allow-Origin",
"value" : "*"
} ]
} ]
But that's not going to help with the CORS issue, since it needs to be in place on the returned resource.
It looks like you can put it into your app.yaml under handlers
based on this doc.
handlers:
- url: /.*
http_headers:
Access-Control-Allow-Origin: http://mygame.appspot.com
Also, you can add this programatically. As explained on enable-cors.org, here are some script implementations:
For Python-based applications in Google App Engine, the self.response.headers.add_header()
method can be used, such as:
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())
For Java-based applications, use 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);
}
And for Go-based applications, use 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)
}
Upvotes: 15