347

I'm making an Ajax.request to a remote PHP server in a Sencha Touch 2 application (wrapped in PhoneGap).

The response from the server is the following:

XMLHttpRequest cannot load http://nqatalog.negroesquisso.pt/login.php. Origin http://localhost:8888 is not allowed by Access-Control-Allow-Origin.

How can I fix this problem?

sideshowbarker
  • 62,215
  • 21
  • 143
  • 153
Ricardo
  • 10,019
  • 8
  • 23
  • 37
  • 20
    while using jQuery, setting `dataType: 'jsonp',` does the trick – amit Oct 11 '12 at 12:45
  • 11
    by the way that is not the response from the server. To be precise that error is issued on the client side. – matteo Feb 01 '13 at 17:41
  • 2
    The jsonp trick probably doesn't work anymore, fyi: http://stackoverflow.com/questions/12216208/chrome-now-blocking-all-jsonp-requests-from-https-to-http – drewww Aug 19 '13 at 18:30
  • 8
    Note, since I just wasted half a day chasing this bug - If the server side script fails with an internal server error, the browser may interpret it as if the request wasn't allowed due to `Access-Control-Allow-Origin` and report this as the error. – troelskn Sep 02 '13 at 13:02
  • 1
    [There's an extension for that!](http://stackoverflow.com/a/24320882/274502) – cregox Jul 07 '14 at 16:48
  • 2
    @troelskn You just saved my life. I was searching for some CORS mistake since 3 days, and it was simply a little Spring configuration problem causing a 500, which I solved in 5 minutes once I read your comment and I actually looked for it. Thank you! – Alexis Dufrenoy Jan 18 '17 at 09:19
  • @alexis-dufrenoy Can you please tell me what is required to change in JAVA Spring configuration – Irshad Khan Aug 11 '20 at 10:23

18 Answers18

379

I wrote an article on this issue a while back, Cross Domain AJAX.

The easiest way to handle this if you have control of the responding server is to add a response header for:

Access-Control-Allow-Origin: *

This will allow cross-domain Ajax. In PHP, you'll want to modify the response like so:

<?php header('Access-Control-Allow-Origin: *'); ?>

You can just put the Header set Access-Control-Allow-Origin * setting in the Apache configuration or htaccess file.

It should be noted that this effectively disables CORS protection, which very likely exposes your users to attack. If you don't know that you specifically need to use a wildcard, you should not use it, and instead you should whitelist your specific domain:

<?php header('Access-Control-Allow-Origin: http://example.com') ?>
meager
  • 209,754
  • 38
  • 307
  • 315
Matt Mombrea
  • 6,565
  • 2
  • 17
  • 19
  • 4
    I'll contact my server provider. Thanks – Ricardo Apr 13 '12 at 15:04
  • 8
    Are there any security concerns with this? [This answer](http://stackoverflow.com/a/9327231/1431728), for example, says "JavaScript is limited by the "same origin policy" for security reasons, For example, a malicious script cannot contact a remote server and send sensitive data from your site." – JohnK Nov 02 '12 at 18:14
  • 4
    Awesome, I just put this in my node.js server file: response.writeHead(200, { 'Content-Type': contentType, 'Access-Control-Allow-Origin': '*' }); And it worked. Thanks! – vbullinger Nov 29 '12 at 04:33
  • 25
    JohnK, yes, the wildcard is going to allow any domain to send requests to your host. I recommend replacing the asterisk with a specific domain that you will be running scripts on. – Nick Dec 20 '12 at 19:33
  • 1
    Uh, you shouldn't even suggest the wildcard. It's a massive security no no and should be used only if you really know what you're doing, see http://code.google.com/p/html5security/wiki/CrossOriginRequestSecurity It's scary to see this answer upvoted so many times. – jfrej May 17 '13 at 12:21
  • 7
    It's interesting that you think the wildcard shouldn't even be suggested @jfrej. It all depends on your goal. For example, the reason we used the wildcard (and posted this answer) was because we were building an embedded widget for any site to use. – Matt Mombrea May 24 '13 at 12:26
  • 2
    it's worth noting that wildcard Origin cannot be used with Access-Control-Allow-Credentials – Ali Gangji Jun 17 '13 at 17:45
  • Working with Asp Mvc Api, i also needed this answer to make all the peaces come together http://stackoverflow.com/questions/12405459/how-to-do-ajax-post-cross-domain-with-custom-headers/14739573#14739573 – Andrey Aug 07 '13 at 22:14
  • Where do you add this in rails 5? – rigdonmr Oct 12 '16 at 21:57
  • I did the same. I have this in my header, but still same issue. – Umair Iftikhar Jan 01 '20 at 15:28
  • Here is my error link. https://stackoverflow.com/questions/59553639/cross-origin-request-blocked-in-my-c-language-api – Umair Iftikhar Jan 01 '20 at 15:29
64

If you don't have control of the server, you can simply add this argument to your Chrome launcher: --disable-web-security.

Note that I wouldn't use this for normal "web surfing". For reference, see this post: Disable same origin policy in Chrome.

One you use Phonegap to actually build the application and load it onto the device, this won't be an issue.

Community
  • 1
  • 1
Travis Webb
  • 13,507
  • 6
  • 51
  • 101
  • Thanks. But my app is running on mobile devices, I cant pass arguments to my webview wrapper. – Ricardo Apr 13 '12 at 16:52
  • Don't you test your app in a browser first? How do you debug? – Travis Webb Apr 13 '12 at 17:33
  • Yes i debug in a Chrome browser, but the app wont run on chrome. It will be on phonegap webview witch i cant control. – Ricardo Apr 16 '12 at 10:25
  • how to heck do you do this? I've looking and can't find this setting inside of chrome. – Jamie Hutber Mar 06 '13 at 15:11
  • 4
    read the answer: **you can simply add this argument to your Chrome launcher**. There is no setting for this inside Chrome – Travis Webb Mar 06 '13 at 16:43
  • @TravisWebb from CLI you can open the browser by typing /PATH_TO_CHROME/Chrome.app --args --disable-web-security – Eddy Ferreira Jan 03 '15 at 01:23
  • This is not a good recommendation - it will only mask the problem and make it work on your own development machine. Taking this approach means that your app will break in production since your users won't have the security disabled. Follow the accepted answer above to properly fix this issue. – providencemac Jan 05 '16 at 15:13
  • 2
    Of course it's insecure. The OP is asking for a way around the security measures. – Travis Webb Jan 17 '16 at 07:28
  • it used to be working but I guess in chrome 49 it doesn't! – omid.n Mar 07 '16 at 09:01
  • update: what you need to do is to use --user-data-dir and --disable-web-security flags altogether(chrome 49+). – omid.n Mar 07 '16 at 09:19
42

If you're using Apache just add:

<ifModule mod_headers.c>
    Header set Access-Control-Allow-Origin: *
</ifModule>

in your configuration. This will cause all responses from your webserver to be accessible from any other site on the internet. If you intend to only allow services on your host to be used by a specific server you can replace the * with the URL of the originating server:

Header set Access-Control-Allow-Origin: http://my.origin.host
Reza S
  • 8,402
  • 3
  • 49
  • 82
18

If you have an ASP.NET / ASP.NET MVC application, you can include this header via the Web.config file:

<system.webServer>
  ...

    <httpProtocol>
        <customHeaders>
            <!-- Enable Cross Domain AJAX calls -->
            <remove name="Access-Control-Allow-Origin" />
            <add name="Access-Control-Allow-Origin" value="*" />
        </customHeaders>
    </httpProtocol>
</system.webServer>
Peter Mortensen
  • 28,342
  • 21
  • 95
  • 123
C. Augusto Proiete
  • 15,781
  • 2
  • 38
  • 56
  • 2
    .NET MVC People, LOOK here! I'm actually going to type up a solution and point to this answer on my blog so that people can find it easier. Nothing worse than trying to get past a .NET/MVC hurdle and finding nothing but PHP/jQuery solutions. Thanks @Caio-Proiete – ottoflux Nov 04 '13 at 14:02
  • 1
    How comes this doesn't work for me? I'm using Chrome and trying to access yahoo finance page from my localhost. – newman Jul 07 '14 at 18:13
  • 1
    thanks it worked for me. I have added in the server side code project (web.config). – ethem Mar 19 '15 at 23:13
15

This was the first question/answer that popped up for me when trying to solve the same problem using ASP.NET MVC as the source of my data. I realize this doesn't solve the PHP question, but it is related enough to be valuable.

I am using ASP.NET MVC. The blog post from Greg Brant worked for me. Ultimately, you create an attribute, [HttpHeaderAttribute("Access-Control-Allow-Origin", "*")], that you are able to add to controller actions.

For example:

public class HttpHeaderAttribute : ActionFilterAttribute
{
    public string Name { get; set; }
    public string Value { get; set; }
    public HttpHeaderAttribute(string name, string value)
    {
        Name = name;
        Value = value;
    }

    public override void OnResultExecuted(ResultExecutedContext filterContext)
    {
        filterContext.HttpContext.Response.AppendHeader(Name, Value);
        base.OnResultExecuted(filterContext);
    }
}

And then using it with:

[HttpHeaderAttribute("Access-Control-Allow-Origin", "*")]
public ActionResult MyVeryAvailableAction(string id)
{
    return Json( "Some public result" );
}
Peter Mortensen
  • 28,342
  • 21
  • 95
  • 123
badMonkey
  • 1,657
  • 1
  • 22
  • 22
  • 1
    WebApi 2 has this built in now. http://www.asp.net/web-api/overview/security/enabling-cross-origin-requests-in-web-api – Matt Frear Jan 26 '14 at 14:17
10

As Matt Mombrea is correct for the server side, you might run into another problem which is whitelisting rejection.

You have to configure your phonegap.plist. (I am using a old version of phonegap)

For cordova, there might be some changes in the naming and directory. But the steps should be mostly the same.

First select Supporting files > PhoneGap.plist

enter image description here

then under "ExternalHosts"

Add a entry, with a value of perhaps "http://nqatalog.negroesquisso.pt" I am using * for debugging purposes only.

enter image description here

steve0hh
  • 627
  • 6
  • 15
8

This might be handy for anyone who needs to an exception for both 'www' and 'non-www' versions of a referrer:

 $referrer = $_SERVER['HTTP_REFERER'];
 $parts = parse_url($referrer);
 $domain = $parts['host'];

 if($domain == 'google.com')
 {
         header('Access-Control-Allow-Origin: http://google.com');
 }
 else if($domain == 'www.google.com')
 {
         header('Access-Control-Allow-Origin: http://www.google.com');
 }
lewsid
  • 1,859
  • 2
  • 17
  • 19
  • Pointed me in the right direction in resolving ACAO error with azure. Whilst I had added allowed hostname of googledrive. URL used needs to be https://googledrive/ NOT https://www.googledrive/ – Kildareflare Nov 12 '13 at 00:54
7

This is because of same-origin policy. See more at Mozilla Developer Network or Wikipedia.

Basically, in your example, you need load the http://nqatalog.negroesquisso.pt/login.php page only from nqatalog.negroesquisso.pt, not localhost.

Peter Mortensen
  • 28,342
  • 21
  • 95
  • 123
antyrat
  • 26,266
  • 9
  • 69
  • 74
7

I've run into this a few times when working with various APIs. Often a quick fix is to add "&callback=?" to the end of a string. Sometimes the ampersand has to be a character code, and sometimes a "?": "?callback=?" (see Forecast.io API Usage with jQuery)

Community
  • 1
  • 1
Francis Baptiste
  • 425
  • 5
  • 13
7

I will give you a simple solution for this one. In my case I don't have access to a server. In that case you can change the security policy in your Google Chrome browser to allow Access-Control-Allow-Origin. This is very simple:

  1. Create a Chrome browser shortcut
  2. Right click short cut icon -> Properties -> Shortcut -> Target

Simple paste in "C:\Program Files\Google\Chrome\Application\chrome.exe" --allow-file-access-from-files --disable-web-security.

The location may differ. Now open Chrome by clicking on that shortcut.

Peter Mortensen
  • 28,342
  • 21
  • 95
  • 123
Dibish
  • 7,811
  • 20
  • 53
  • 97
7

If you're writing a Chrome Extension and get this error, then be sure you have added the API's base URL to your manifest.json's permissions block, example:

"permissions": [
    "https://itunes.apple.com/"
]
Jonathan Cross
  • 623
  • 7
  • 16
itzg
  • 1,002
  • 13
  • 10
6

if you're under apache, just add an .htaccess file to your directory with this content:

Header set Access-Control-Allow-Origin: *

Header set Access-Control-Allow-Headers: content-type

Header set Access-Control-Allow-Methods: *
aydow
  • 3,081
  • 1
  • 18
  • 33
chispitaos
  • 509
  • 6
  • 12
5

If you get this in Angular.js, then make sure you escape your port number like this:

var Project = $resource(
    'http://localhost\\:5648/api/...', {'a':'b'}, {
        update: { method: 'PUT' }
    }
);

See here for more info on it.

RevanthKrishnaKumar V.
  • 1,779
  • 1
  • 19
  • 33
Marius
  • 3,531
  • 3
  • 25
  • 30
5

In Ruby on Rails, you can do in a controller:

headers['Access-Control-Allow-Origin'] = '*'
Peter Mortensen
  • 28,342
  • 21
  • 95
  • 123
fuzzyalej
  • 5,675
  • 1
  • 29
  • 49
5

You may make it work without modifiying the server by making the broswer including the header Access-Control-Allow-Origin: * in the HTTP OPTIONS' responses.

In Chrome, use this extension. If you are on Mozilla check this answer.

forzagreen
  • 1,776
  • 25
  • 30
4

We also have same problem with phonegap application tested in chrome. One windows machine we use below batch file everyday before Opening Chrome. Remember before running this you need to clean all instance of chrome from task manager or you can select chrome to not to run in background.

BATCH: (use cmd)

cd D:\Program Files (x86)\Google\Chrome\Application\chrome.exe --disable-web-security
RevanthKrishnaKumar V.
  • 1,779
  • 1
  • 19
  • 33
abksharma
  • 515
  • 6
  • 23
1

In Ruby Sinatra

response['Access-Control-Allow-Origin'] = '*' 

for everyone or

response['Access-Control-Allow-Origin'] = 'http://yourdomain.name' 
Mikhail Chuprynski
  • 2,065
  • 2
  • 24
  • 38
0

When you receive the request you can

var origin = (req.headers.origin || "*");

than when you have to response go with something like that:

res.writeHead(
    206,
    {
        'Access-Control-Allow-Credentials': true,
        'Access-Control-Allow-Origin': origin,
    }
);
RevanthKrishnaKumar V.
  • 1,779
  • 1
  • 19
  • 33
Alessandro Annini
  • 1,461
  • 1
  • 15
  • 30