Origin is not allowed by Access-Control-Allow-Origin
Asked Answered
H

18

371

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?

Heinie answered 13/4, 2012 at 14:50 Comment(5)
while using jQuery, setting dataType: 'jsonp', does the trickPlacido
by the way that is not the response from the server. To be precise that error is issued on the client side.Bakehouse
The jsonp trick probably doesn't work anymore, fyi: #12216708Kinkajou
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.Homeroom
There's an extension for that!Atp
P
390

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') ?>
Pocked answered 13/4, 2012 at 14:54 Comment(7)
Are there any security concerns with this? This answer, 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."Trevortrevorr
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!Rania
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.Alcaide
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 code.google.com/p/html5security/wiki/CrossOriginRequestSecurity It's scary to see this answer upvoted so many times.Tadio
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.Pocked
it's worth noting that wildcard Origin cannot be used with Access-Control-Allow-CredentialsGrunberg
Working with Asp Mvc Api, i also needed this answer to make all the peaces come together #12405959Lycaonia
I
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.

Ivie answered 13/4, 2012 at 16:50 Comment(10)
Thanks. But my app is running on mobile devices, I cant pass arguments to my webview wrapper.Heinie
Don't you test your app in a browser first? How do you debug?Ivie
Yes i debug in a Chrome browser, but the app wont run on chrome. It will be on phonegap webview witch i cant control.Heinie
how to heck do you do this? I've looking and can't find this setting inside of chrome.Tm
read the answer: you can simply add this argument to your Chrome launcher. There is no setting for this inside ChromeIvie
@TravisWebb from CLI you can open the browser by typing /PATH_TO_CHROME/Chrome.app --args --disable-web-securityFishworm
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.Counteract
Of course it's insecure. The OP is asking for a way around the security measures.Ivie
it used to be working but I guess in chrome 49 it doesn't!Infrared
update: what you need to do is to use --user-data-dir and --disable-web-security flags altogether(chrome 49+).Infrared
C
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
Critchfield answered 21/8, 2012 at 7:15 Comment(2)
And don't forget to load module: a2enmod headersScott
how to load module:a2enmod headers ?Lahnda
T
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>
Tomtit answered 13/8, 2013 at 20:56 Comment(3)
.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-ProieteProtectorate
How comes this doesn't work for me? I'm using Chrome and trying to access yahoo finance page from my localhost.Wailoo
thanks it worked for me. I have added in the server side code project (web.config).Drown
S
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" );
}
Sexton answered 6/6, 2013 at 15:24 Comment(1)
WebApi 2 has this built in now. asp.net/web-api/overview/security/…Immotile
L
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

Landgraviate answered 23/4, 2012 at 4:46 Comment(0)
F
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');
 }
Fugato answered 18/6, 2013 at 17:37 Comment(1)
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 googledrive NOT googledriveMima
D
7

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

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

Drinking answered 13/4, 2012 at 14:51 Comment(2)
But I need to load the webservice from a mobile device, I would a bypass this?Heinie
Well you need to make some server-side changes or use JSONP en.wikipedia.org/wiki/JSONPDrinking
A
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)

Alternation answered 19/12, 2012 at 0:7 Comment(0)
V
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.

Vindictive answered 16/10, 2013 at 4:1 Comment(0)
S
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/"
]
Size answered 1/2, 2014 at 18:18 Comment(0)
A
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: *
Analects answered 2/9, 2015 at 18:31 Comment(0)
P
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.

Pamplona answered 18/4, 2013 at 9:23 Comment(0)
B
5

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

headers['Access-Control-Allow-Origin'] = '*'
Burmaburman answered 3/9, 2013 at 15:51 Comment(1)
what controller do you put this in if it's an ajax call? Can I see more code context?Frissell
C
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.

Chandachandal answered 7/4, 2015 at 12:26 Comment(0)
B
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
Bangor answered 11/3, 2013 at 6:37 Comment(0)
L
1

In Ruby Sinatra

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

for everyone or

response['Access-Control-Allow-Origin'] = 'http://yourdomain.name' 
Longdrawnout answered 7/6, 2015 at 20:16 Comment(0)
S
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,
    }
);
Soria answered 9/9, 2014 at 23:10 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.