93

I can't figure out why my .htaccess header settings doesn't work.

My .htaccess file content:

Header set Access-Control-Allow-Origin *
Header always set Access-Control-Allow-Methods "POST, GET, OPTIONS, DELETE, PUT"
Header always set Access-Control-Allow-Headers "*"
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ index.php [QSA,L]

But when I remove Header's and add them in index.php then everything works fine.

header("Access-Control-Allow-Origin: *");
header("Access-Control-Allow-Methods: PUT, GET, POST, DELETE, OPTIONS");
header("Access-Control-Allow-Headers: *");

What am i missing?

Koen.
  • 25,449
  • 7
  • 83
  • 78
user1401592
  • 939
  • 1
  • 7
  • 4

11 Answers11

137

This should work:

Header add Access-Control-Allow-Origin "*"
Header add Access-Control-Allow-Headers "origin, x-requested-with, content-type"
Header add Access-Control-Allow-Methods "PUT, GET, POST, DELETE, OPTIONS"
imbrizi
  • 3,788
  • 1
  • 25
  • 26
24

Just for the record, I was running into the exact same problem and none of the answers worked.

I used a headers checker tool: http://www.webconfs.com/http-header-check.php

I was testing with my IP (http://192.0.2.1/upload) and what came back was the following:

HTTP/1.1 301 Moved Permanently => 
Date => Sat, 10 Jan 2015 04:03:35 GMT
Server => Apache/2.2.21 (Win32) mod_ssl/2.2.21 OpenSSL/1.0.0e PHP/5.3.8 mod_perl/2.0.4 Perl/v5.10.1
Location => http://192.0.2.1/upload/
Content-Length => 380
Connection => close
Content-Type => text/html; charset=iso-8859-1

There was a redirection happening and the AJAX request does not honor/follow redirects.

It turned out to be the missing slash at the end of the domain (http://192.0.2.1/upload/)

I tested again with slash at the end and I got this below. Added a slash in the script too, and it was now working.

HTTP/1.1 200 OK => 
Date => Sat, 10 Jan 2015 04:03:53 GMT
Server => Apache/2.2.21 (Win32) mod_ssl/2.2.21 OpenSSL/1.0.0e PHP/5.3.8 mod_perl/2.0.4 Perl/v5.10.1
X-Powered-By => PHP/5.3.8
Access-Control-Allow-Origin => *
Access-Control-Allow-Methods => PUT, GET, POST, DELETE, OPTIONS
Access-Control-Allow-Headers => *
Content-Length => 1435
Connection => close
Content-Type => text/html

Use this tool to test if your headers are good and to troubleshoot what is happening.

Patrick Mevzek
  • 10,995
  • 16
  • 38
  • 54
Miro
  • 8,402
  • 3
  • 34
  • 72
  • 5
    I have 11 tabs open right now trying to solve this. This answer should be in more places. – JDavis Nov 17 '16 at 19:43
  • With mine, I needed to remove the trailing slash. So glad I found this. Spent so much time troubleshooting this when I new it should have been working hours ago. – gorelog Jan 24 '18 at 02:59
  • have my uptick for the headers tool, even if this didnt solve it for me – mdkb Aug 08 '22 at 02:46
11

I have a shared hosting on GoDaddy. I needed an answer to this question, too, and after searching around I found that it is possible.

I wrote an .htaccess file, put it in the same folder as my action page. Here are the contents of the .htaccess file:

Header add Access-Control-Allow-Origin "*"
Header add Access-Control-Allow-Headers "origin, x-requested-with, content-type"
Header add Access-Control-Allow-Methods "PUT, GET, POST, DELETE, OPTIONS"

Here is my ajax call:

    $.ajax({
        url: 'http://www.mydomain.com/myactionpagefolder/gbactionpage.php',  //server script to process data
        type: 'POST',
        xhr: function() {  // custom xhr
            myXhr = $.ajaxSettings.xhr();
            if(myXhr.upload){ // check if upload property exists
                myXhr.upload.addEventListener('progress',progressHandlingFunction, false); // for handling the progress of the upload
            }
            return myXhr;
        },
        //Ajax events
        beforeSend: beforeSendHandler,
        success: completeHandler,
        error: errorHandler,
        // Form data
        data: formData,
        //Options to tell JQuery not to process data or worry about content-type
        cache: false,
        contentType: false,
        processData: false
    });

See this article for reference:

Header set Access-Control-Allow-Origin in .htaccess doesn't work

Community
  • 1
  • 1
TARKUS
  • 2,170
  • 5
  • 34
  • 52
9

Be careful on:

 Header add Access-Control-Allow-Origin "*"

This is not judicious at all to grant access to everybody. It's preferable to allow a list of know trusted host only...

Header add Access-Control-Allow-Origin "http://aaa.example"
Header add Access-Control-Allow-Origin "http://bbb.example"
Header add Access-Control-Allow-Origin "http://ccc.example"

Regards,

Patrick Mevzek
  • 10,995
  • 16
  • 38
  • 54
Alex
  • 225
  • 3
  • 1
  • 4
    This won't work. Access-Control-Allow-Origin isn't allowed multiple values. You need to dynamically set the header based on the value of the Origin request header. – Quentin Mar 11 '19 at 14:35
7

I activated the Apache module headers a2enmod headers, and the issue has been solved.

Mogsdad
  • 44,709
  • 21
  • 151
  • 275
truthblue82
  • 129
  • 1
  • 6
  • Errors in the log weren't clear as to why the changes I was making would fail and this answer helped a great deal. `sudo a2enmod headers` and a restart got it working! – cchana Aug 31 '18 at 20:02
6

Try this in the .htaccess of the external root folder

<IfModule mod_headers.c>
    Header set Access-Control-Allow-Origin "*"
</IfModule>

Be careful with doing Header add Access-Control-Allow-Origin "*" This is not judicious at all to grant access to everybody. I think you should user:

<IfModule mod_headers.c>
    Header set Access-Control-Allow-Origin "http://example.com"
</IfModule>
Ryan M
  • 18,333
  • 31
  • 67
  • 74
Vo Quoc Cuong
  • 4,448
  • 1
  • 14
  • 6
4

I +1'd Miro's answer for the link to the header-checker site http://www.webconfs.com/http-header-check.php. It pops up an obnoxious ad every time you use it, but it is, nevertheless, very useful for verifying the presence of the Access-Control-Allow-Origin header.

I'm reading a .json file from the javascript on my web page. I found that adding the following to my .htaccess file fixed the problem when viewing my web page in IE 11 (version 11.447.14393.0):

<FilesMatch "\.(json)$">
  <IfModule mod_headers.c>
    Header set Access-Control-Allow-Origin "*"
  </IfModule>
</FilesMatch>

I also added the following to /etc/httpd.conf (Apache's configuration file):

AllowOverride All

The header-checker site verified that the Access-Control-Allow-Origin header is now being sent (thanks, Miro!).

However, Firefox 50.0.2, Opera 41.0.2353.69, and Edge 38.14393.0.0 all fetch the file anyhow, even without the Access-Control-Allow-Origin header. (Note: they might be checking IP addresses, since the two domains I was using are both hosted on the same server, at the same IPv4 address.)

However, Chrome 54.0.2840.99 m (64-bit) ignores the Access-Control-Allow-Origin header and fails anyhow, erroneously reporting:

No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin '{mydomain}' is therefore not allowed access.

I think this has got to be some sort of "first." IE is working correctly; Chrome, Firefox, Opera and Edge are all buggy; and Chrome is the worst. Isn't that the exact opposite of the usual case?

Dave Burton
  • 2,960
  • 29
  • 19
1

To complete the most upvoted answer, I want to add the case whenever the options to the header is not add in a response request, you could add the always keyword from Apache.

In my case i needed to add the access control allow origin in the response of the redirection and not in the result of the redirection.

And a redirection is giving the 302 code status so the header wasn't filled with the correct information.

In this case I needed to add it :

Header always set Access-Control-Allow-Origin "*"

For more information you can check this thread : Apache: difference between "Header always set" and "Header set"?

Vindic
  • 627
  • 6
  • 8
0

After spending half a day with nothing working. Using a header check service though everything was working. The firewall at work was stripping them

0

try this:

<IfModule mod_headers.c>
     Header set Access-Control-Allow-Credentials true
     Header set Access-Control-Allow-Origin "your domain"
     Header set Access-Control-Allow-Headers "X-Requested-With"
</IfModule>

It's preferable to allow a list of know trusted host.

behnam shateri
  • 1,223
  • 13
  • 18
0

If anyone else is trying this, the most upvoted answer should work. However, if you are having issues it could be possible the browser has cached the REQUEST. To confirm append a query string.

Simon Song
  • 134
  • 1
  • 8