Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
243 views
in Technique[技术] by (71.8m points)

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

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?

Question&Answers:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

To fully CORS-enable an Apache web server, you need to have it configured to look like this:

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, though some browsers may not support 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: *, some browsers may not support it yet.

  • Access-Control-Expose-Headers: set to include any response headers beyond Expires, Cache-Control, Content-Type, Pragma, Last-Modified, and Content-Language that your frontend code needs to read. 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 some browsers may not 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 (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, the specific changes and additions that would need to made are these:

  • Use Header always set instead of just Header set.

  • Use mod_rewrite to handle the OPTIONS by just sending back 200 OK with those headers.

  • The request has Access-Control-Request-Headers:authorization so in the 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 no need to include them in Access-Control-Allow-Headers.

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

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


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

1.4m articles

1.4m replys

5 comments

56.9k users

...