When I run this code on client side instead of server it returns the error. If it is run on the server it works fine. I'm using meteor. I'm struggling to find a solution online. Can someone explain what I'm doing wrong here?
Path: Code on client
googleMapsClient.geocode({
address: 'My test address'
}, function(err, response) {
if (!err) {
console.log(response.json.results);
}
});
Error: in console
Failed to load https://maps.googleapis.com/maps/api/geocode/json?address=Test%20address&key=MYKEY: The value of the 'Access-Control-Allow-Origin' header in the response must not be the wildcard '*' when the request's credentials mode is 'include'. Origin 'http://localhost:3000' is therefore not allowed access. The credentials mode of requests initiated by the XMLHttpRequest is controlled by the withCredentials attribute.
This seems to be answered by the author of the library here. It's a good idea to first go through the github issues for a given library in order to find common mistakes. The idea is that the library is supposed to be used on the server side, for the client side use you would use google's API.
Related
My Flutter web app needs to call an API when the user submits a contact form. The API is that of a discord bot that proceeds to post the message in a specific channel on my Discord server. This setup works fine for two other apps that are using the same dependencies and the same production environment (Firebase hosting), but on this specific app it throws the following error:
Access to XMLHttpRequest at
'https://discordapp.com/api/channels/689799838509957177/messages' from
origin 'https://autonet.tk' has been blocked by CORS policy: Response
to preflight request doesn't pass access control check: No
'Access-Control-Allow-Origin' header is present on the requested
resource.
If I add the header 'Access-Control-Allow-Origin': '*' to the request, I just get a XMLHttpRequest error
My code:
import 'package:http/http.dart' as http;
var resp = await http.post(
"https://discordapp.com/api/channels/689799838509957177/messages",
headers: {
'Authorization': "Bot " + botToken,
},
body: {
"content": "NEW MESSAGE: " + body
});
Making it harder to triangulate the root cause is the fact that this runs fine on my local machine. It's only once I deploy the app to Firebase hosting that I get that CORS error.
Another thing worth noting is that on the Discord side, there is no configuration that I had to make in order to accept the incoming request for the other two web apps that work fine using the same code. (There is no list of allowed hosts).
'Access-Control-Allow-Origin' it's a header that must be in the response, not in the request. For more information, I suggest you this read:
https://stackoverflow.com/a/20035319/14106548
EDIT:
After a small research I think you are calling the wrong endpoint. This is why the response doesn't have the proper header attached.
The endpoint is:
https://discord.com/api
For more info look at: https://discord.com/developers/docs/reference
I created login FE and finished it.
And as per usual my goto for ajax was Axios. My code is as follows.
const baseUrl = http://localhost:5000/project/us-central1/api
Axios.post(
`${baseUrl}/v1/user/login`,
{ ...data },
{
headers: {
Authorization: 'Basic auth...'
}
},
).then(r => console.log(r).catch(e =>console.log(e));
Now when i try to send request to my local firebase cloud function.
I get a 400 bad request.
after checking the request, I was wondering why it wasn't sending any preflight request, which it should do(to the best of my knowledge) but instead I saw a header named Sec-Fetch-Mode. I searched anywhere it's a bit abstract. And I can't seem to figure anything why my request still fails.
Is there anything Im missing in my config of axios?
My FE is running on a VSCode Plugin named live server(http://127.0.0.1:5500)
Also, my firebase cloud function has enabled cors
// cloud function expres app
cors({
origin: true
})
Any insights would be very helpful.
The OPTIONS request is actually being sent, because you are sending a cross-origin request with an Authorization header which is considered as non-simple. It doesn't show in developer tools because of a feature/bug in Chrome 76 & 77. See Chrome not showing OPTIONS requests in Network tab for more information.
The preflight request is a mechanism that allows to deny cross-origin requests on browser side if the server is not CORS aware (e.g: old and not maintained), or if it explicitly wants to deny cross-origin requests (in both cases, the server won't set the Access-Control-Allow-Origin header). What CORS does could be done on server side by checking the Origin header, but CORS actually protects the user at browser level. It blocks the disallowed cross-origin requests even before they are sent, thus reducing the network traffic, the server load, and preventing the old servers from receiving any cross-origin request by default.
On the other hand, Sec-Fetch-Mode is one of the Fetch metadata headers (Sec-Fetch-Dest, Sec-Fetch-Mode, Sec-Fetch-Site and Sec-Fetch-User). These headers are meant to inform the server about the context in which the request has been sent. Based on this extra information, the server is then able to determine if the request looks legitimate, or simply deny it. They exist to help HTTP servers mitigate certain types of attacks, and are not related to CORS.
For example the good old <img src="https://mybank.com/giveMoney?amount=9999999&to=evil#attacker.com"> attack could be detected on server side because the Sec-Fetch-Dest would be set to "image" (this is just a simple example, implying that the server exposes endpoints with the GET method with unsafe cookies for money operations which is obviously not the case in real life).
As a conclusion, fetch metadata headers are not designed to replace preflight requests, but rather to coexist with them since they fulfill different needs. And the 400 error has likely nothing to do with these, but rather with the request that does not comply with the endpoint specification.
You are missing a dot on your spread operator, this is the correct syntax:
{ ...data }
Note the three dots before “data”.
Please see the use of spread operators with objects here:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax
I'm using VueJS with vue-request for http requests. I'm trying to subscribe an user to a Mailchimp list but Mailchimp uses BasicAuth, so I'm doing as such:
scope.$http.post('https://us15.api.mailchimp.com/3.0/lists/listid/members',
{...mydata...}, {headers: {Authorization: 'Basic myencodedAPIkey'}})
But I get an error from the API: 401 Unauthorized - Your request did not include an API key.
So I check the Network log on Chrome and the Authorization is on my headers like this: **Access-Control-Request-Headers: authorization** but it should be like **Authorization: myencodedAPIkey**
On the Console the error appears as:
XMLHttpRequest cannot load
https://us15.api.mailchimp.com/3.0/lists/listid/members. Response
to preflight request doesn't pass access control check: No
'Access-Control-Allow-Origin' header is present on the requested
resource. Origin 'http://127.0.0.1:8000' is therefore not allowed
access. The response had HTTP status code 401.
When I use Postman it works just fine as the header is correctly sent.
This problem seems to have been solved here with setting the header on every request
https://laracasts.com/discuss/channels/vue/how-to-solve-the-allow-control-allow-cross-in-the-vuejs-header-request-setting?page=2
and here through setting it once
Vue-Request not sending Authorization Header
You are getting CORS error, when you are trying to request from one host to another, and the 'another' part does not allow it to happen. To prevent this error you can use webpack proxy configuration, so this way you do not have cross origin request, but I don't know how you will deal with this in production environment if your api does not allow cross origin requests.
In a project I'm working on, our devServer configuration is as follow
proxy: {
'/api': {
target: 'http://localhost:8080/'
}
},
with this, any request happening on /api/any/url will be redirect to localhost:8080/api/any/url
I encountered a very weird error today within phantomjs, that I'm turning to the community for. The expected JSON response of an API I was invoking with phantomJS was not being returned, but rather the result was a status of failure.
onResourceReceived() showed a 200 http status code for the resource in question
onLoadFinished() shows a status of fail
After debugging this for sometime, I noticed that the site was returning a non standard content-type header on the response. Rather than content-type of "application/json" the header being returned was "application/servicename-1.0+json".
To verify this, we spun up a local webserver that served a similar header, and sure enough phantom js cannot load the page. Setting the response header to "application/json" and phantomjs correctly renders the page and sets the page objects page.plainText variable. I've included the testing script below.
Has anyone encountered anything like this before?
Any suggestions on how to handle this issue within phantomjs?
The simplest and quickest solution I can think of (not involving editing PhantomJS' source code and compiling it) is to set up a simple local proxy server in front of PhantomJS that would rewrite the incorrect header.
It could be something like fiddler2, Charles Proxy or a simple node.js script, like this quick-n-dirty example:
// npm install proxy-tamper
var proxy = require('proxy-tamper').start({port: 3000});
proxy.tamper(/api.truelocal.com.au.*$/, function (request) {
request.onResponse(function (response) {
if ('content-type' in response.headers && response.headers['content-type'] == 'application/servicename-1.0+json') {
response.headers['content-type'] = 'application/json';
}
response.complete();
});
});
Then have PhantomJS use it:
phantomjs --proxy=127.0.0.1:3000 script.js
Note that this won't work for secure pages.
Well, after asking this question I did a deeper dive in the phantomjs source. Looks like there is some fairly strict detection on application/json here: https://github.com/Vitallium/qtwebkit/blob/phantomjs/Source/WebCore/dom/DOMImplementation.cpp#L368
In my Meteor (1.2) application, I make a client-side HTTP.get call over https to a remote server supporting CORS.
var getUrl= "https://remoteserver/;
HTTP.call('GET', getUrl , {}, function (error, response) {
console.log (response);
}
Now, the issue is that set-cookie string is present in HTTP headers of the response of such HTTP call in Chrome's DevTools' Network tab.
However when I call console.log (response) , they're not included. Actually only these 3 properties are printed in response['headers']:
Content-Type
cache-control
last-modified
Digging more in, I found out on Meteor Docs that
Cookies are deliberately excluded from the headers as they are a security risk for this transport. For details and alternatives, see the SockJS documentation.
Now, on the linked SockJS docs, it says that
Basically - cookies are not suited for SockJS model. If you want to authorise a session - provide a unique token on a page, send it as a first thing over SockJS connection and validate it on the server side. In essence, this is how cookies work.
I found this this answer about sockJS but it looks outdated an not specific to Meteor.
The remote server expects me to use cookie-set header, so I have no choice. Also, for established scalability reasons, the HTTP.call must be done client-side (server-side was not an issue at all)
What solution / workaround can I adopt?
This package looks to be designed to help in situations like this, though I have not used it:
https://atmospherejs.com/dandv/http-more