How to CORS-enable Apache web server (including preflight and custom headers)?

我怕爱的太早我们不能终老 提交于 2019-12-17 04:36:06

问题


General:

Request URL:x/site.php
Request Method:OPTIONS
Status Code:302 Found
Remote Address:x.x.x.x:80

Response Headers:

view source
Access-Control-Allow-Headers:Content-Type
Access-Control-Allow-Origin:*
Access-Control-Max-Age:300
Cache-Control:no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Content-Length:0
Content-Type:text/html; charset=UTF-8
Date:Thu, 02 Mar 2017 14:27:21 GMT
Expires:Thu, 19 Nov 1981 08:52:00 GMT
Location:y
Pragma:no-cache
Server:Apache/2.4.25 (Ubuntu)

Request Headers:

view source
Accept:*/*
Accept-Encoding:gzip, deflate, sdch
Accept-Language:en-US,en;q=0.8
Access-Control-Request-Headers:authorization
Access-Control-Request-Method:POST
Cache-Control:no-cache
Connection:keep-alive
DNT:1
Host:x
Origin:http://127.0.0.1:3000
Pragma:no-cache
Referer:http://127.0.0.1:3000/
User-Agent:Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.90 Safari/537.36

Apache virtualhost config looks as so:

    <IfModule mod_headers.c>
           Header set Access-Control-Allow-Origin "http://127.0.0.1:3000"
           Header set Access-Control-Allow-Origin "http://127.0.0.1"
           Header set Access-Control-Max-Age "300"
           Header set Access-Control-Allow-Credentials "true"
           Header set Access-Control-Allow-Headers "Origin, X-Requested-With, Content-Type, Accept"
           Header set Access-Control-Allow-Methods "POST, GET, PUT, DELETE, PATCH, OPTIONS"
    </IfModule>

The preflight request is skipping the apache config and hitting my webapp directly, which does a redirect (hence the 302 and the location: y).

I don't know why the preflight request is not being handled by apache?


回答1:


The two main things you need to change/add are:

  • Use Header always set instead of just Header set
  • Use mod_rewrite to handle the OPTIONS by just sending back a 200 OK with those headers

So to enable the request in the question to work, here’s a minimal(ish) config snippet:

Header always set Access-Control-Allow-Origin "*"
Header always set Access-Control-Allow-Headers "Authorization"
Header always set Access-Control-Allow-Methods "GET"
Header always set Access-Control-Expose-Headers "Content-Security-Policy, Location"
Header always set Access-Control-Max-Age "600"

RewriteEngine On
RewriteCond %{REQUEST_METHOD} OPTIONS
RewriteRule ^(.*)$ $1 [R=200,L]

Longer explanation at https://benjaminhorn.io/code/setting-cors-cross-origin-resource-sharing-on-apache-with-correct-response-headers-allowing-everything-through/

Some general notes on what values to set for the various Access-Control- response headers:

  • Access-Control-Allow-Headers: you must set it to include any header names your request sends except    CORS-safelisted header names or so-called “forbidden” header names (names of headers set by the browser that you can’t set in your JavaScript); the spec alternatively allows the * wildcard as its value—so you can try it someday, but no browser supports it yet: Chrome bug, Firefox bug, Safari bug

  • Access-Control-Allow-Methods: the spec alternatively allows the * wildcard—but again, as with Access-Control-Allow-Headers: *, no browsers support it yet

  • Access-Control-Expose-Headers: you must set to include any response headers your client code needs to read beyond Cache-Control,Content-Language,Content-Type, Expires, Last-Modified and Pragma—which are exposed by default (a lot of people forget to set this and end up baffled about why they can’t read the value of a particular response header); again the spec alternatively allows the * wildcard here, but no browsers support it yet

  • Access-Control-Max-Age: Chrome has an upper limit of 600 (10 minutes) hardcoded, so there’s no point in setting a higher value for it than that (Firefox may respect it, but Chrome will just throttle it down to 10 minutes if you set it higher, and Safari limits it to only 5 minutes)

So then, about the particular request shown in the question, here are some specific notes:

  • Your request has Access-Control-Request-Headers:authorization so in your Apache config, add Authorization in the Access-Control-Allow-Headers response header too.

  • Origin is a “forbidden” header name set by the browser, and Accept is a CORS-safelisted header name, so you don’t need to include them in Access-Control-Allow-Headers

  • Your request sends no Content-Type, so it isn’t needed in Access-Control-Allow-Headers in the response (and never needed for GET requests and otherwise only needed if the type is other than application/x-www-form-urlencoded, text/plain, or multipart/form-data)

  • For Access-Control-Allow-Methods, your request seems to just be a GET, so unless you plan to also make POST/PUT/DELETE/PATCH requests, no point in explicitly including them



来源:https://stackoverflow.com/questions/42558221/how-to-cors-enable-apache-web-server-including-preflight-and-custom-headers

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!