ChatGPT解决这个技术问题 Extra ChatGPT

Origin is not allowed by Access-Control-Allow-Origin

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?

while using jQuery, setting dataType: 'jsonp', does the trick
by the way that is not the response from the server. To be precise that error is issued on the client side.
The jsonp trick probably doesn't work anymore, fyi: stackoverflow.com/questions/12216208/…
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.

u
user229044

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') ?>

I'll contact my server provider. Thanks
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."
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!
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.
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.
C
Community

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.


Thanks. But my app is running on mobile devices, I cant pass arguments to my webview wrapper.
Don't you test your app in a browser first? How do you debug?
Yes i debug in a Chrome browser, but the app wont run on chrome. It will be on phonegap webview witch i cant control.
read the answer: you can simply add this argument to your Chrome launcher. There is no setting for this inside Chrome
Of course it's insecure. The OP is asking for a way around the security measures.
R
Reza S

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

And don't forget to load module: a2enmod headers
how to load module:a2enmod headers ?
P
Peter Mortensen

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>

.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
How comes this doesn't work for me? I'm using Chrome and trying to access yahoo finance page from my localhost.
thanks it worked for me. I have added in the server side code project (web.config).
t
tagurit

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" );
}

WebApi 2 has this built in now. asp.net/web-api/overview/security/…
s
steve0hh

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

https://i.stack.imgur.com/PSSXx.png

then under "ExternalHosts"

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

https://i.stack.imgur.com/U7fxd.png


l
lewsid

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');
 }

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 googledrive
J
Jonathan Cross

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/"
]

P
Peter Mortensen

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:

Create a Chrome browser shortcut 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.


C
Community

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)


t
tagurit

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.


But I need to load the webservice from a mobile device, I would a bypass this?
Well you need to make some server-side changes or use JSONP en.wikipedia.org/wiki/JSONP
a
aydow

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: *

P
Peter Mortensen

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

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

what controller do you put this in if it's an ajax call? Can I see more code context?
R
RevanthKrishnaKumar V.

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.


f
forzagreen

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.


R
RevanthKrishnaKumar V.

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

M
Mikhail Chuprynski

In Ruby Sinatra

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

for everyone or

response['Access-Control-Allow-Origin'] = 'http://yourdomain.name' 

R
RevanthKrishnaKumar V.

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,
    }
);