JQuery / AJAX: Cross-Origin Request Blocked - javascript

I have the following script (simplfied) that grabs some data from a local php file:
$(document).ready(function(){
var current_date = "x=y";
$.ajax
({
url: 'work/get_cal.php',
type: 'post',
data : current_date,
async: false,
success: function(result)
{
alert('never gets this far');
}
});
});
However I get a cross domain error, even though everything is on the same server. Has anyone had this issue before?
Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://www.mywebsite.co.uk/work/get_cal.php. (Reason: CORS header 'Access-Control-Allow-Origin' missing).

Add following line to get_cal.php
header('Access-Control-Allow-Origin: *');
This will allow to make Cross-Origin Request.

From comments to the original question for future Googlers.
The code used absolute paths and ended up in different domain "level" when the page was accessed with www and the script was requesting without www. This caused CORS problem.

Same Origin Policy permits running scripts in a browser and allows making requests to pages on with the SAME URI Scheme, hostname and port number. This is implemented for security within most of the browsers.
I personally use Chrome with Web Security Disabled during testing. Use the --disable-web-security parameter to enable this in your Chrome.
I strongly advice creating a seperate shortcut for development & testing purposes and NOT to use this option for your regular browsing...
"C:\<path_to_chrome_folder>\chrome.exe" --user-data-dir="C:/Chrome dev session" --disable-web-security
--user-data-dir is used to store the session details and other browser data, thus keeping is separate from your regular browsing data.
--disable-web-security disables the security and thus the Same Origin Policy warning.
Hope this helps...!

Related

How to solve 'Redirect has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header'?

I am working on an app using Vue js.
According to my setting I need to pass to a variable to my URL when setting change.
<!-- language: lang-js -->
$.get('http://172.16.1.157:8002/firstcolumn/' + c1v + '/' + c1b, function (data) {
// some code...
});
But when my app hit on URL, it shows the following message.
Failed to load http://172.16.1.157:8002/firstcolumn/2017-03-01/2017-10-26: Redirect from 'http://172.16.1.157:8002/firstcolumn/2017-03-01/2017-10-26' to 'http://172.16.1.157:8002/firstcolumn/2017-03-01/2017-10-26/' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:8080' is therefore not allowed access.
In addition to what awd mentioned about getting the person responsible for the server to reconfigure (an impractical solution for local development) I use a change-origin chrome plugin like this:
Moesif Orign & CORS Changer (use to be free but now wants a work email address >_>)
Allow CORS: Access-Control-Allow-Origin
You can make your local dev server (ex: localhost:8080) to appear to be coming from 172.16.1.157:8002 or any other domain.
In case the 2nd plugin link breaks in the future or the plugin writer decides to capitalize off the fame of this thread, open your browser's
plugin marketplace and search "allow cors", there's going to be a
bunch of them.
Thanks all, I solved by this extension on chrome.
Allow CORS: Access-Control-Allow-Origin
If you have control over your server, you can use PHP:
<?PHP
header('Access-Control-Allow-Origin: *');
?>
Ask the person maintaining the server at http://172.16.1.157:8002/ to add your hostname to Access-Control-Allow-Origin hosts, the server should return a header similar to the following with the response-
Access-Control-Allow-Origin: yourhostname:port
Using npm:
To allow cross-origin requests install 'cors':
npm i cors
Add this in the server-side:
let cors = require("cors");
app.use(cors());
When you have this problem with Chrome, you don't need an Extension.
Start Chrome from the Console:
chrome.exe --user-data-dir="C:/Chrome dev session" --disable-web-security
Maybe you have to close all Tabs in Chrome and restart it.
I will assume that you're a front-end developer only and that you don't have access to the backend of the application (regarding the tags of the question).
Short answer on how to properly solve this in your case? You can't, you'll need somebody else.
What is this about?
You need to understand that CORS is a security thing, it's not just here to annoy you just for fun.
It's purpose is to mainly prevent the usage of a (malicious) HTTP call from a non-whitelisted frontend to your backend with some critical mutation.
You could give a look to this YouTube video or any other one really, but I recommend a visual video because text-based explanation can be quite hard to understand.
You also need to understand that if you use Postman or any other tool to try your API call, you will not get the CORS issue. The reason being that those tools are not Web frontends but rather some server-based tools.
Hence, don't be surprised if something is working there but not in your Vue app, the context is different.
Now, how to solve this?
Depending of the framework used by your backend team, the syntax may be quite different but overall, you'll need to tell them to provide something like Access-Control-Allow-Origin: http://localhost:3000 (or any other port you'll be using).
PS: Using Access-Control-Allow-Origin: * would be quite risky because it would allow anybody to access it, hence why a stricter rule is recommended.
If you're using a service, like an API to send SMS, payment, some Google console or something else really, you'll need to allow your localhost in the dashboard of the service. Ask for credentials to your manager or Tech Lead.
If you have access to the backend, you could it yourself as shown here (ExpressJS in this example): https://flaviocopes.com/cors/
How to hack it in a dirty way?
If you're in a damn hurry and want to get something really dirty, you could use a lot of various hacks a listed in the other answers, here's a quick list:
use any extension who is able to create a middleware and forward the request to the backend (it will work because it's not directly coming from your frontend)
force your browser to disable CORS, not sure how this would actually solve the issue
use a proxy, if you're using Nuxt2, #nuxtjs/proxy is a popular one but any kind of proxy (even a real backend will do the job)
any other hack related somehow to the 3 listed above...
At the end, solving the CORS issue can be done quite fast and easily. You only need to communicate with your team or find something on your side (if you have access to the backend/admin dashboard of some service).
I heavily do recommend trying get it right from the beginning because it's related to security and that it may be forgotten down the road...
The approved answer to this question is not valid.
You need to set headers on your server-side code
app.use((req,res,next)=>{
res.setHeader('Access-Control-Allow-Origin','*');
res.setHeader('Access-Control-Allow-Methods','GET,POST,PUT,PATCH,DELETE');
res.setHeader('Access-Control-Allow-Methods','Content-Type','Authorization');
next();
})
You can also try a chrome extension to add these headers automatically.
Hello If I understood it right you are doing an XMLHttpRequest to a different domain than your page is on. So the browser is blocking it as it usually allows a request in the same origin for security reasons. You need to do something different when you want to do a cross-domain request. A tutorial about how to achieve that is Using CORS.
When you are using postman they are not restricted by this policy. Quoted from Cross-Origin XMLHttpRequest:
Regular web pages can use the XMLHttpRequest object to send and receive data from remote servers, but they're limited by the same origin policy. Extensions aren't so limited. An extension can talk to remote servers outside of its origin, as long as it first requests cross-origin permissions.
To add the CORS authorization to the header using Apache, simply add the following line inside either the <Directory>, <Location>, <Files> or <VirtualHost> sections of your server config (usually located in a *.conf file, such as httpd.conf or apache.conf), or within a .htaccess file:
Header set Access-Control-Allow-Origin "*"
And then restart apache.
Altering headers requires the use of mod_headers. Mod_headers is enabled by default in Apache, however, you may want to ensure it's enabled.
I had the same problem in my Vue.js and SpringBoot projects. If somebody work with spring you can add this code:
#Bean
public FilterRegistrationBean simpleCorsFilter() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
CorsConfiguration config = new CorsConfiguration();
config.setAllowCredentials(true);
// *** URL below needs to match the Vue client URL and port ***
config.setAllowedOrigins(Collections.singletonList("http://localhost:8080"));
config.setAllowedMethods(Collections.singletonList("*"));
config.setAllowedHeaders(Collections.singletonList("*"));
source.registerCorsConfiguration("/**", config);
FilterRegistrationBean bean = new FilterRegistrationBean<>(new CorsFilter(source));
bean.setOrder(Ordered.HIGHEST_PRECEDENCE);
return bean;
}
I found solution in this article Build a Simple CRUD App with Spring Boot and Vue.js
You are making a request to external domain 172.16.1.157:8002/ from your local development server that is why it is giving cross origin exception.
Either you have to allow headers Access-Control-Allow-Origin:* in both frontend and backend or alternatively use this extension cors header toggle - chrome extension unless you host backend and frontend on the same domain.
Try running this command in your terminal and then test it again.
curl -H "origin: originHost" -v "RequestedResource"
Eg:
If my originHost equals https://localhost:8081/ and my RequestedResource equals https://example.com/
My command would be as below:
curl -H "origin: https://localhost:8081/" -v "https://example.com/"
If you can notice the following line then it should work for you.
< access-control-allow-origin: *
Hope this helps.
Do specify #CrossOrigin(origins = "http://localhost:8081")
in Controller class.
You can solve this temporarily by using the Firefox add-on, CORS Everywhere. Just open Firefox, press Ctrl+Shift+A , search the add-on and add it!
You won't believe this,
Make sure to add "." at the end of the "url"
I got a similar error with this code:
fetch(https://itunes.apple.com/search?term=jack+johnson)
.then( response => {
return response.json();
})
.then(data => {
console.log(data.results);
}).catch(error => console.log('Request failed:', error))
The error I got:
Access to fetch at 'https://itunes.apple.com/search?term=jack+johnson'
from origin 'http://127.0.0.1:5500' has been blocked by CORS policy:
No 'Access-Control-Allow-Origin' header is present on the requested
resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
But I realized after a lot of research that the problem was that I did not copy the
right URL address from the iTunes API documentation.
It should have been
https://itunes.apple.com/search?term=jack+johnson.
not
https://itunes.apple.com/search?term=jack+johnson
Notice the dot at the end
There is a huge explanation about why the dot is important quoting issues about DNS and character encoding but the truth is you probably do not care. Try adding the dot it might work for you too.
When I added the "." everything worked like a charm.
I hope it works for you too.
install:
npm i cors
Then include cors():
app.get("/list",cors(),(req,res) =>{
});
In addition to the Berke Kaan Cetinkaya's answer.
If you have control over your server, you can do the following in ExpressJs:
app.use(function(req, res, next) {
// update to match the domain you will make the request from
res.header("Access-Control-Allow-Origin", "YOUR-DOMAIN.TLD");
res.header("Access-Control-Allow-Methods", "GET,HEAD,OPTIONS,POST,PUT");
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
next();
});
https://enable-cors.org/server_expressjs.html
I tried this code,and that works for me.You can see the documentation in this link
var io = require("socket.io")(http, {
cors: {
origin: "*",
methods: ["GET", "POST"]
}
})
The reason that I came across this error was that I hadn't updated the path for different environments.
you have to customize security for your browser or allow permission through customizing security. (it is impractical for your local testing)
to know more about please go through the link.
https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS
These errors may be caused due to follow reasons, ensure the following steps are followed. To connect the local host with the local virtual machine(host). Here, I'am connecting http://localhost:3001/ to the http://abc.test Steps to be followed:
1.We have to allow CORS, placing Access-Control-Allow-Origin: in header of request
may not work. Install a google extension which enables a CORS request.*
2.Make sure the credentials you provide in the request are valid.
3.Make sure the vagrant has been provisioned. Try vagrant up --provision this make the localhost connect to db of the homestead.
Try changing the content type of the header. header:{ 'Content-Type' : 'application/x-www-form-urlencoded; charset=UTF-8;application/json' }
this point is very important.
Another solution to this problem in a specific scenario :
If
AWS APIGW is your backend with authentication enabled and
authentication fails,
your browser may end up complaining about CORS even if CORS is enabled in APIGW. You also need to enable CORS for 4XX as follows
API:YourAPI > Resources > /YourResource > Actions > Enable CORS > Gateway Responses for yourAPI check Default 4XX
Authentication will still fail but it won't look like CORS is the root cause
$.get('https://172.16.1.157:8002/firstcolumn/' + c1v + '/' + c1b, function (data) {
// some code...
});
Just put "https" .

How can solve Access-Control-Allow-Origin error?

I have setup a small web application on heroku.com in Django which returns JsonResponse you can see it here.
{
name: "shubham",
college: "MAIT",
subject: "java"
}
And I also setup server locally on my computer which accepts that JSON and it appends with HTML element here my javascript file :
$(function (){
$.ajax({
type:'GET',
url:'https://justgiveme.herokuapp.com/',
dataType :"Json",
contentType: "application/json; charset=utf-8",
success: function(data) {
alert("Success !");
},
error : function()
{
alert("failed !");
}
});
});
but when I open localhost it gives me alert("failed !") instead of alert("success !"); .
I have check on Chrome console and I found this error :
Any helpful suggestion is appreciable .
You need to enable Cross-Origin-Resource-Sharing (CORS) on your heroku app. Right now its failing because the request isn't coming from the domain which the first resource was retrieved from. In your case, 127.0.0.1.
Here's a starting point for Django on CORS: http://www.django-rest-framework.org/topics/ajax-csrf-cors/
The error you are seeing is because the browser sends a preflight request to check if a cross origin request is allowed. You can see it being sent when viewing the Network tab in the Chrome Inspector. It will be an OPTIONS request to the url that is specified in the ajax.
In order to resolve this issue, the server needs to let the browser know that cross origin requests are allowed. To do this, Django must respond to the preflight request with the Access-Control-Allow-Origin header specified. The header's value must be either be the website you are requesting from or "*" to allow any website.
//Any website
Access-Control-Allow-Origin: *
//Specific website
Access-Control-Allow-Origin: http://www.example.com
A resource makes a cross-origin HTTP request when it requests a
resource from a different domain than the one which the first resource
itself serves. For example, an HTML page served from
http://domain-a.com makes an src request for
http://domain-b.com/image.jpg. Many pages on the web today load
resources like CSS stylesheets, images and scripts from separate
domains.
For security reasons, browsers restrict cross-origin HTTP requests
initiated from within scripts. For example, XMLHttpRequest follows
the same-origin policy. So, a web application using XMLHttpRequest
could only make HTTP requests to its own domain. To improve web
applications, developers asked browser vendors to allow XMLHttpRequest
to make cross-domain requests
you can read more about CORS here .
Detailed explanation of how to setup CORS in Django ?
This is because of no provision in the REST API to handle Cross-Origin-Resource-Request (CORS). To enable it in the REST API, we need django-cors-headers as recommended in Django REST Framework documentation. The minimal settings required are as follows.
Step 0 - install django-cors-headers .
pip install django-cors-headers
Step 1 - In settings.py, add the following entry in INSTALLED_APPS tuple.
INSTALLED_APPS = (
'......',
'corsheaders',
'......'
)
Step 2 - In settings.py, add the following entries at the top of MIDDLEWARE_CLASSES tuple.
MIDDLEWARE_CLASSES = (
'corsheaders.middleware.CorsMiddleware',
'django.middleware.common.CommonMiddleware',
)
Step 3 - Add the following flag variable in settings.py
CORS_ORIGIN_ALLOW_ALL = True
you can read more about CORS in django here .
We are done !!

No 'Access-control-allow-origin' header is present on the requested resource error with json and jquery

I use an API that is on a different server and i got an CORS error I think. The strange thing is that it first worked with no problem, then i got this error message
XMLHttpRequest cannot load http://www.thecocktaildb.com/api/json/v1/1/random.php? tagmode=any&type=POST&format=jsonp. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'myadress.com' is therefore not allowed acces
i added crossDomain: "true" and it worked for a day. Now it doesn't work again and i've searched and tried a lot of solutions i've found. But nothing works. What is the problem and how do i fix it? Tried jsonp instead of json with and without type:post and the &callback=? does nothing. I've even installed the CORS enable extension for chrome. But alwways the same error, I have no control over the API itself or the server hosting it. How can I fix this? Below is my code.
function random() {
$(document).ready(function () {
$.getJSON("http://www.thecocktaildb.com/api/json/v1/1/random.php", {
tagmode: "any",
type: "POST",
format: 'jsonp',
crossDomain: "true"
}, function (data) {
console.log(data);
var result = "";
$.each(data.drinks, function (index, value) {
result += "<p>" + value.idDrink + "<p>";
result += "<p>" + value.strDrink + "<p>";
});
$('#result').html(result);
console.log(result);
});
});
}
I think you can make some modification for bypass CORS error. but target environment can also block CORS request. When I used Paypal checkout, I encountered same problem. Paypal environment doesn't accept CORS request.
So that you can try to make this call over server side.
If I understood it right you are doing an AJAX call to a different domain than your page is on. So the browser is blocking it as it usually allows a request in the same origin for security reasons. You need to do something different when you want to do a cross-domain request. A tutorial about how to achieve that is Using CORS.
Regular web pages can use the XMLHttpRequest object to send and
receive data from remote servers, but they're limited by the same
origin policy. Extensions aren't so limited. An extension can talk to
remote servers outside of its origin, as long as it first requests
cross-origin permissions.
Solution :
For allowing access to specific domain only:
response.addHeader("Access-Control-Allow-Origin", "http://www.thecocktaildb.com");
Check this blog post.

Adobe Connect API with Jquery

I am trying to create a simple login form for my Adobe Connect account, however it's not working, I'm getting the error:
No 'Access-Control-Allow-Origin' header
However I'm doing other Ajax calls just fine on my machine.
Here's some example code that I'm using.
var request $.ajax({
url: 'http://example.com/api/xml?action=login&login=' + username + '&password=' + password
type: "GET"
});
request.done(function(){
...
})
Does anyone have any suggestions?
Your local machine calls are working because you're making calls inside the same domain. As soon as you try to do ajax calls to something outside the bounds of the caller's domain you'll run into issues with the browser's Same-Origin policy.
Basically it's a security policy that allows scripts to run on pages originating from the same site (comprised by the combination between schema, hostname and port. eg. mysite != mysite:8080) So if you have an ajax call executed from a site running on mysite to a site running on mysite:8080, the browser will consider this a same-origin policy hence blocking that request.
You should read about CORS (Cross-Origin Resource Sharing) in order to find options to help you relax the same-origin policy.

how Postman send requests? ajax, same origin policy

I have found this very useful Chrome extension called Postman. This is a very useful extension especially when you are into programming RESTful applications.
One thing I am confused on is that how this plugin/extension able to send POST request successfully on different domains?
I tried voting in a poll using Postman like this.
After submitting that, the vote was actually counted in, but when I tried doing that using AJAX and JavaScript, it fails, because of different origin policy of browsers.
How is that even possible?
Here is my code using jQuery. I used that in my computer though, localhost.
init: function() {
$.ajax({
url: 'http://example.com/vote.php',
type:'POST',
dataType: 'html',
data: {
id: '1'
},
success: function(data) {
if ( data == 'voted' ) {
$('.set-result').html( 'you already voted. try again after 24 hours' );
} else {
$('.set-result').html( 'successfully voted' );
}
}
});
},
Chrome packaged apps can have cross domain permissions. When you install Postman it promts you that this app will access any domain.
By placing */* in permissions section of your manifest file, you can do this.
Read more here:
https://developer.chrome.com/extensions/xhr.html
You can add the following header to sent Ajax request in postman.
Content-Type application/json
X-Requested-With XMLHttpRequest
Screenshot
Sounds like the site that hosts the poll (the "vote.php" script) needs to have an "Access-Control-Allow-Origin" header set to allow posting from a list of sites (or all sites).
A value of * for the header will allow posting from any website:
Access-Control-Allow-Origin: *
i.e. You could put the following at the top of vote.php
header('Access-Control-Allow-Origin: *');
Chrome extensions and apps are not subject to the same security limitations placed on normal webpages.
Additional debugging tips:
If you're trying to access remote services from web pages you have open on your local file system in your browser, you might find your browser applies different security rules to them than it does to files served from a web service.
e.g. If you open local files from a locational like C:\MyDocuments\weboot\index.htm (Windows) or \Users\joe\Sites\index.html (Mac) in your browser your AJAX request might not work, even with the header specified in most browsers.
Apple's Safari applies almost no cross domain restrictions to files opened locally but Firefox is much more strict about what it permits, with Chrome somewhere in the middle. Running a web server locally (e.g. on http://localhost/) is a good idea to avoid unexpected behaviour.
Additionally, other libraries that provide functions to handle Ajax requests (such as AngularJS) may require other headers to be set on the server by default. You can usually see the reason for failure in a browser debug console.
2021 Oct
In my investigation, I found out that you need an extra field in the header of your request. So simply add the following key-value into the header:
key: X-Requested-With | value: XMLHttpRequest

Categories

Resources