Closed j-planet closed 7 years ago
In addition, i'm also setting withCredentials to true in the config.
I just ran into this issue as well and it only seems to happen for me on Mac. I spent a good 3 days and nights trying to debug my network and decided on a whim to try this using a vanilla XHR request and realized the problem wasn't my network, but axios.
I too am doing cross-site requests with credentials set to true. Looking at the network request, you get an ERR_EMPTY_RESPONSE and it's like the request failed before it even left the browser.
This is my config:
const myApi = axios.create({
baseURL: 'http://someUrl/someEndpoint',
timeout: 10000,
withCredentials: true,
transformRequest: [(data) => JSON.stringify(data.data)],
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
}
});'
If I get a chance I will try to look into this further.
Oh good I'm not crazy. :) Please look into this if possible.
Turns out my issue was unrelated to Axios. Cisco Anyconnect was blocking options requests from my machine... because reasons?
Cross domain requests don't require any extra config. It will fall back to using XDomainRequest
for older IE. https://github.com/mzabriskie/axios/blob/master/lib/adapters/xhr.js#L22
Can you provide more details? What browser, OS, version of axios, any error messages.
I can't speak for Jenny but something in particular this library does causes requests to be block by Cisco Anyconnect default security which means it's possible other security settings do this too. I'm trying to track this down but no luck so far.
This can be reproduced by making a cross site request on a mac installed with cisco Anyconnect and possibly other VPN clients.
My environment is:
Note that the same request works with curl.
Thanks for looking into this!
With CORS a preflight request is made to the server to see if the request is allowed. You will need to have your server respond to requests that haveOPTIONS
as request method by setting the header Acces-Control-Allow-Origin: *
which will allow requests from any origin. Alternatively you can allow for just certain origins Acces-Control-Allow-Origin: http://example.com
.
Yes, I understand that. But the server is not mine. I'm using a Baas (backend-as-a-service). And they have already added my domain to the allowed list. I have checked that other people using said Baas have not had such problems.
I'm just going off the error message that you provided, but based on that it doesn't sound like you baas has things working for you. It wouldn't fail using curl because the cross origin security is only a limitation within the browser.
Can you open the network tab in your browser and share what you get as the response to the OPTIONS request? Hopefully seeing the response data and headers will help debug this issue.
Thanks
Here are the headers:
Here's the response headers from GitHub when I use axios to get my user profile from their API:
You can see that GitHub adds the Access-Control-Allow-Origin: *
. The response from your Baas is missing any Access-Control
type headers.
I see I see hmm. Sorry for the super late reply. Let me look into this a bit more. Thank you very much.
I'm not sure if what I'm seeing is related or not. Basically, I can send an auth request to our remote server and get back a cookie, but then subsequent calls to the server don't send the cookies along with them, resulting in an error.
Here are the headers from the POST
call to login:
And now a followup GET
call:
The IP address listed under origin
is my own, so that shouldn't be an issue. If this is the wrong place for this, I am happy to make a new issue, or attach to the appropriate existing one.
As a new wrinkle; I've tested a follow-up GET
call using just straight XHR, and the cookie is sent along just fine. Doing the same call through Axios, however, results in the same issue I mentioned above.
Ugh. Please disregard - I wasn't sending things as expected through Axios :)
Im also facing the same issue. OPTIONS Call goes thru, but POST calls gets stuck into cors. http://stackoverflow.com/questions/36907693/axios-cors-issue-with-github-oauth-not-getting-access-token
How is such a HUGE issue, not addressed?
+1
+1
+1
+1
+1
+1
+1
@dsacramone what is the issue that you are seeing? It seems that most of the issues being reported are problems with server or false alarms. If there is a reproducible error that I can look at I am happy to work on a fix.
getting this too
XMLHttpRequest cannot load https://en.wikipedia.org/w/api.php?action=opensearch&format=json&search=fish. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:3000' is therefore not allowed access.
also getting it using fetch to note. i think its chrome have recently made their request setting policy more strict, i think it will need some sort of header (not sure what tho).
here's some example (both served over https)
Example 1 - Works fine
axios.get('https://randomuser.me/api/')
.then(function (response) {
console.log(response.data);
})
.catch(function (error) {
console.log(error);
});
Exampel 2 - Not working - showing error ?
axios.get('https://en.wikipedia.org/w/api.php?action=opensearch&format=json&search=fish')
.then(function (response) {
console.log(response.data);
})
.catch(function (error) {
console.log(error);
});
here's the error response
[object Error] {
config: [object Object] {
data: undefined,
headers: [object Object] { ... },
maxContentLength: -1,
method: "get",
timeout: 0,
transformRequest: [object Object] { ... },
transformResponse: [object Object] { ... },
url: "https://en.wikipedia.org/w/api.php?action=opensearch&format=json&search=fish",
validateStatus: function validateStatus(status) {
return status >= 200 && status < 300;
},
xsrfCookieName: "XSRF-TOKEN",
xsrfHeaderName: "X-XSRF-TOKEN"
},
response: undefined
}
something that might be relevant is in the transformResponse ? i'm wondering what PROTECTION_PREFIX bit means?
[object Object] {
0: function transformResponse(data) {
/*eslint no-param-reassign:0*/
if (typeof data === 'string') {
data = data.replace(PROTECTION_PREFIX, '');
try {
data = JSON.parse(data);
} catch (e) { /* Ignore */ }
}
return data;
}
}
even trying
mode: 'no-cors' in fetch still gives this error
i'm sure the answers pretty simple and just needs some sort of header, just not sure what tho, will keep playing around.
the wikipedia api might just be a wonky example,same error on others?
I delete this code,can work: axios.defaults.withCredentials = true
I got the wikipedia api to work fine with jsonp
var jsonp = require('jsonp');
// search for 'frog'
jsonp('https://en.wikipedia.org/w/api.php?action=opensearch&search=frog&format=json', null, function (err, data) {
if (err) {
console.error(err.message);
} else {
console.log(data);
}
});
No extra configs required.
Getting the same error with axios. Here's my React component:
import React, { Component } from 'react'
import axios from 'axios'
export default class User extends Component {
constructor(props){
super(props)
// axios.defaults.withCredentials = true
const config = {
method: 'get',
url: 'https://api.airbnb.com/v2/users/2917444?client_id=3092nxybyb0otqw18e8nh5nty&_format=v1_legacy_show',
headers: {'X-Requested-With': 'XMLHttpRequest'},
responseType: 'json',
withCredentials: true,
}
axios.request(config)
.then(response => { console.log('response: ', response) });
}
render() {
return (
<div>User</div>
)
}
}
Note: I can hit the API perfectly fine with Node request.
I'm running into the same error that @Sinistralis is. On the latest version of chrome in Mac OSX I'm getting net::ERR_EMPTY_RESPONSE
on CORS requests that are made properly (my server handles all the CORS headers including OPTIONS just fine). It's strange because on iOS10 safari, the exact same code works with no problems. Will try to investigate a little more on my own to see how this might be resolved.
On an older mac (10.11) with the latest version of chrome, I cannot reproduce this error with the exact same code. This is very odd indeed. You may be able to reproduce by visiting this very simple app: http://lights.suyashkumar.com and inspecting the console (code is here. On some machines there will be no error and it'll redirect you to login. On others it won't redirect and will leave you on the main page.
Solved my error. For me, it was an issue with assigning a header in config.headers
with a null value on application start (it pulls a value out of local storage, and initially, nothing is there). Assigning the value to be an empty string when the value is null solves the problem. I wonder if this is something that can or should be handled within axios (not sure if there's value in passing null headers to xhr if it breaks sometimes).
For others with a similar issue, I found that some VPN clients can also block OPTIONS requests (see here)
The misleading CORS error is still in axios. The fetch
polyfill supports mode: 'no-cors'
to fix this issue.
We need to do these kinds of requests to make requests against machines in other environments we operate, as well as on the same machine on different ports!
@dreki Please provide the description of the issue you mentioned.
You can't do a thing on the client-side, when the server simply does not accept requests from your origin. If you could, we'd have a huge security leak here (and with "we" I mean the whole internet)...
I think axios acts and reacts totally conformy here.
The important Response header is Access-Control-Allow-Origin
which basically sets the valid origins, that are allowed to call this server-side service. If your client is not calling from any of these configured origins, the request will be declined with a console error like this:
XMLHttpRequest cannot load http://localhost:8080/v1/api/search?q=candles. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:9999' is therefore not allowed access.
You're not on the guest list.
Fixed my problem.
Was trying to access my express api on localhost:3000
from my vue app on localhost:8080
, but was getting an error back.
Turns out you need to add http://
to make it work.
So use http://localhost:3000
instead of localhost:3000
when doing dev testing.
I had the same problem with wikmedia api. looking into their CORS page (https://www.mediawiki.org/wiki/Manual:$wgCrossSiteAJAXdomains) I added origin=* to the request and it fixed the issue.
axios.get('https://en.wikipedia.org/w/api.php?action=opensearch&format=json&origin=*&search=Albert') .then(function(res) { console.log(res); }) .catch(function(err) { console.log('Error: =>' + err); })
Even though I got the scary cors error message, my request was hitting the server.
XMLHttpRequest cannot load "...url here...". No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:3000' is therefore not allowed access.
Axios team, can you please fix???
@mellogarrett This is not an axios related problem. Read this: https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS
Important cite:
"For security reasons, browsers restrict cross-origin HTTP requests initiated from within scripts. For example, XMLHttpRequest and Fetch follow the same-origin policy. So, a web application using XMLHttpRequest or Fetch could only make HTTP requests to its own domain. To improve web applications, developers asked browser vendors to allow cross-domain requests."
Many of those having this issue probably don't have the server responding to the OPTIONS request. Make sure you have handlers (with CORS headers) for both OPTIONS and POST requests. The client (axios) will first ping OPTIONS and then do the POST.
I've got the same error on Firefox, but not on Chromium. Then I remembered NoScript was there (in Firefox) preventing the request to the remote server. In case you have NoScript (or a similar plugin) installed, check that first. In my case the issue was not related to Axios. Thanks for the great work.
For anyone else googling a fix to this issue, I had all the same symptoms but traced the problem to a php.ini setting on the server.
My preflight OPTIONS request was successful and followed by a proper POST request but I was still getting No 'Access-Control-Allow-Origin' header is present on the requested resource...
similar to @mellogarrett . This seemed totally weird so I used a Chrome plugin to temporarily disable CORS protection. After that, I could see the problem was actually a PHP error:
Deprecated: Automatically populating $HTTP_RAW_POST_DATA is deprecated and will be removed in a future version. To avoid this warning set 'always_populate_raw_post_data' to '-1' in php.ini and use the php://input stream instead. in Unknown on line 0
This post has more info on the problem, but in short, if you're using PHP 5.6 you should uncomment always_populate_raw_post_data
in your php.ini and set to -1
. Hope this saves somebody else a few hours of troubleshooting 🤓
Hey @daltonamitchell It seems like I am having the same issue (conditions suggest that it is the same problem). But I am wondering: How did you figure out the raw post data-error was the problem? When using the chrome plugin you mentioned the CORS request goes through and everything works fine. But even though headers are set correctly I can not get it to work without the plugin. So maybe the deprecation message is just not displayed but the issue might still be there...? Can you give some advice how to check for that?
@RT-TL the plugin is only used to see the response content without CORS blocking it. In my case, for test purposes I was just returning a string like Hello World
so once I disabled CORS I saw something like
Deprecated: Automatically populating $HTTP_RAW_POST_DATA is deprecated and will be removed in a future version. To avoid this warning set 'always_populate_raw_post_data' to '-1' in php.ini and use the php://input stream instead. in Unknown on line 0
Hello World
Make sure you have PHP warnings enabled by adding error_reporting(E_ERROR | E_WARNING | E_PARSE | E_NOTICE)
or error_reporting(E_ALL)
to the top of your controller method. If you still don't see anything I'd just try returning some simple JSON response to check that they look as expected.
Is anyone still experiencing this issue? I'm running into the same:
const instance = axios.create({
baseURL: 'http://localhost/',
responseType: 'json',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
'Authorization': 'test',
'X-Test': 'testing'
}
})
axios.get('v2/portal/bar/foo?')
Response headers
HTTP/1.1 401 Unauthorized
Server: nginx/1.11.10
Date: Fri, 24 Mar 2017 07:12:13 GMT
Content-Type: application/json; charset=UTF-8
Content-Length: 0
Connection: keep-alive
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: POST, PUT, DELETE, GET, OPTIONS
Access-Control-Allow-Headers: *
Request headers
OPTIONS /v2/portal/bar/foo? HTTP/1.1
Host: localhost
Connection: keep-alive
Access-Control-Request-Method: GET
Origin: http://localhost:3000
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.98 Safari/537.36
Access-Control-Request-Headers: authorization,content-type,x-test
Accept: */*
Referer: http://localhost:3000/dashboard/report
Accept-Encoding: gzip, deflate, sdch, br
Accept-Language: en-US,en;q=0.8,fr;q=0.6,nl;q=0.4,zh-TW;q=0.2,zh;q=0.2,zh-CN;q=0.2
I can't figure out why none of my headers are being send correctly.
Same issue here, OPTIONS request is made, but POST request is not.
TLDR: fetch works, axios doesn't unless I use JSON.stingify
So I have also seen the variant of this error where OPTIONS returns 200 with the headers set for cross origin requests, but no POST is made. I use this extension and it starts working as expected. But I am pretty sure there is some sort of issue here. Take a look at my request:
My server is replying with Access-Control-Allow-Origin: *
Here's all the examples with code and screenshots:
Axios:
axios.post('http://localhost:3001/card', { test: 'test' })
fetch:
return fetch('http://localhost:3001/card', {
method: 'POST',
body: { test: 'test' },
})
with JSON.stringify
return fetch('http://localhost:3001/card', {
method: 'POST',
body: JSON.stringify({ test: 'test' }),
})
I was able to make axios work by JSON.stringify
-ing my data like so:
return axios.post('http://localhost:3001/card', JSON.stringify({ test: 'test' }));
I was facing the same problem as @kwhitaker explained, axios was not sending my cookie properly resulting in responses with less information (I suppose due to the security concerns). In the other hand regular XHR request worked fine. Then as @zlyi suggested I just added the line axios.defaults.withCredentials = true;
and everything started worked as expected.
Hello,
Thanks for the great work. Although that were some releases targeting cross-site requests, I still can't get it to work. I dug through the previous posts and tried adding:
to the config. And none of them worked. (If this feature is actually available, updating the readme would help.)
Please advise ASAP. Thank you.