title: Firebase hosting Access-Control-Allow-Origin for app engine URL
body: <p>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 <a href="https://firebase.google.com/docs/hosting/full-config#section-full-firebasejson" rel="noreferrer">deployment documentation</a> and there is no example how to add Access-Control-Allow-Origin header for URL.</p>
  
  <p>Here is what my firebase.json looks like:</p>
  
  <pre><code>{
    "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" : "*"
        } ]
      } ]
    }
  }
  </code></pre>
  
  <p>I've tried to set the CORS using gsutils but it didn't help as well:</p>
  
  <p>Here is my cors.json</p>
  
  <pre><code>[
      {
          "maxAgeSeconds": 3600, 
          "method": ["GET", "POST"], 
          "origin": ["https://project-id.appspot.com/"]
      }
  ]
  </code></pre>
  
  <p>Thanks in advance</p>
  
  <p>SOLUTION:</p>
  
  <p>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. </p>
  
  <p>If your request is a simple one then the following code works:</p>
  
  <pre><code>@Override
  public void doPost(HttpServletRequest req, HttpServletResponse resp) 
      resp.addHeader("Access-Control-Allow-Origin", "*");
      resp.addHeader("Content-Type", "text/csv");
      resp.getWriter().append("Response");
  
  }
  </code></pre>
  
  <p>However if your request is pre-flighted you'll have to override the doOptions method and add the appropriate headers:</p>
  
  <pre><code>@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");
  }
  </code></pre>
  
  <p><a href="https://www.html5rocks.com/static/images/cors_server_flowchart.png" rel="noreferrer">Here</a> is a helpful diagram which clarifies CORS implementation on server:</p>