Flutter Web getting 'XMLHttpRequest' error while making http call - flutter-web

I am trying to query Apache drill running in my local server but i'm getting the below error. Please help me, I tried adding '.htaccess' inside my /web folder of the project as well but it did't work.... Thanks!
http
.post(
'http://localhost:8047/query.json',
headers: <String, String>{
'Content-Type': 'application/json',
'Access-Control-Allow-Headers':
'Origin, Content-Type, Cookie, X-CSRF-TOKEN, Accept, Authorization, X-XSRF-TOKEN, Access-Control-Allow-Origin',
'Access-Control-Expose-Headers': "" 'Authorization, authenticated',
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Methods': 'GET,POST,OPTIONS,DELETE,PUT',
'Access-Control-Allow-Credentials': 'true',
},
body: jsonEncode(<String, String>{
'queryType': 'SQL',
'query':
'select * from dfs.`C:/Users/drill/data/*.parquet`'
}),
)
.then((_response) {
setState(() {
response = jsonDecode(_response.body);
});
}
Error: XMLHttpRequest error.
C:/b/s/w/ir/cache/builder/src/out/host_debug/dart-sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/errors.dart 264:20 get current
packages/http/src/browser_client.dart 84:22 <fn>
C:/b/s/w/ir/cache/builder/src/out/host_debug/dart-sdk/lib/async/zone.dart 1450:54 runUnary
C:/b/s/w/ir/cache/builder/src/out/host_debug/dart-sdk/lib/async/future_impl.dart 143:18 handleValue
C:/b/s/w/ir/cache/builder/src/out/host_debug/dart-sdk/lib/async/future_impl.dart 696:44 handleValueCallback
C:/b/s/w/ir/cache/builder/src/out/host_debug/dart-sdk/lib/async/future_impl.dart 725:32 _propagateToListeners
C:/b/s/w/ir/cache/builder/src/out/host_debug/dart-sdk/lib/async/future_impl.dart 519:7 [_complete]
C:/b/s/w/ir/cache/builder/src/out/host_debug/dart-sdk/lib/async/stream_pipe.dart 61:11 _cancelAndValue
C:/b/s/w/ir/cache/builder/src/out/host_debug/dart-sdk/lib/async/stream.dart 1300:7 <fn>
C:/b/s/w/ir/cache/builder/src/out/host_debug/dart-sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/operations.dart 324:14 _checkAndCall
C:/b/s/w/ir/cache/builder/src/out/host_debug/dart-sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/operations.dart 329:39 dcall
C:/b/s/w/ir/cache/builder/src/out/host_debug/dart-sdk/lib/html/dart2js/html_dart2js.dart 37287:58 <fn>
at Object.createErrorWithStack (http://localhost:62659/dart_sdk.js:4348:12)
at Object._rethrow (http://localhost:62659/dart_sdk.js:37892:16)
at async._AsyncCallbackEntry.new.callback (http://localhost:62659/dart_sdk.js:37886:13)
at Object._microtaskLoop (http://localhost:62659/dart_sdk.js:37718:13)
at _startMicrotaskLoop (http://localhost:62659/dart_sdk.js:37724:13)

I currently have the same error message and it is very misleading. It seems to simply indicate that the request fails for whatever reason.
To debug it, use Chrome's DevTools (Ctrl+Shift+C), go to 'Network' and check there. You will almost certainly see that some parts of the request are not what you intended and that the request failed.
EDIT: Maybe it is a CORS-issue, then this great answer might be helpful: No 'Access-Control-Allow-Origin' header is present on the requested resource—when trying to get data from a REST API

If the above solutions didn't work , It may be just an issue with the device you are running on (Like my case)
in task manager make sure to quit all chrome processes
then
flutter clean
then
flutter run -d chrome
This fixed the problem for me.

How does the response look like?
I had a similar issue and fixed it with this information in the response {'Access-Control-Allow-Origin': '*'}
return ('Any response body', 200, {'Access-Control-Allow-Origin': '*'})
So I also believe that it is a server side issue as well. It may work when the URL is posted in a browser or when using tools like insomnia, but flutter needs this information.

Related

No 'Access-Control-Allow-Origin' header is present on the requested resource. AWS Lambdas

For some reason I started getting this error. The only changes were inside function and everything was working fine. I've no idea why it's appeared for each lambda's function.
Before the bug there were some minor changes just for logic inside the function.
I tried to add it inside lambda as in example below:
headers: {
'Access-Control-Allow-Headers': '*',
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Methods': '*',
'Accept': '*/*',
'Content-Type': 'application/json'
}
But that doesn't help. I tried to add it inside AWS, but no luck.
I don't know what to do and how to solve this.
Help someone please.
Try using this extension on Chrome.
Allow CORS: Access-Control-Allow-Origin

NodeJS fetch("https://www.google.com") says "TypeError: NetworkError when attempting to fetch resource" but it was a 200

My Firefox developer network tab says that the call was a 200 and even shows the page, yet both fetch and axios say that it failed with a network error.
axios call was just ==>
axios.get('https://www.google.com', {
headers: {
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Methods': 'GET, PUT, POST, DELETE, HEAD, OPTIONS, PATCH'
}
}).then((response) => {
alert(response);
}, (error) => {
alert("error = " + error);
});
This has got to be something simple/stupid but I just can't figure it out. :-(
Oh yeah. Edge does the same thing . . . .
(EDITED) MORE DETAILS
If I add an UNBLOCK CORS extension to my browser AND comment out my two header lines, it works. With the header lines, it doesn't work -- so they must be wrong, but I don't see how.
i.e.
axios.get('https://www.google.com', {
headers: {
// 'Access-Control-Allow-Origin': '*',
// 'Access-Control-Allow-Methods': 'GET, PUT, POST, DELETE, HEAD, OPTIONS, PATCH'
}
}).then((response) => {
works
Any ideas?
As you already discovered, the issue is that this is a cross-origin request and that is only allowed with CORS.
However, it seems you misunderstood CORS.
The whole point of the same-origin policy is that people should not be able to do what you are trying to do here - send a request in the browser from a page of domain A to a page of domain B. The only exception is when B (not A!) explicitly allows receiving requests from domain A (or from domain *).
So, in your case, Google (not you) would have to send those headers in the response in order to tell the browser that this request is permitted and it should return the results to your code. Of course, Google isn't doing that, so even though it is a 200, you never get the result because the browsers see that in that 200 response those CORS headers are missing.
The only way for you to make that work without relying on the extension to disable this mechanism (other than asking Google to add an exception for your domain 😉) would be to proxy this request through your server. If your server sends the request to Google and not the script in your page, it will work of course, since it's a policy that the browsers enforce, and the server is not inside a browser. So, you'd have to send a request to your server which would forward it to Google and then pass the response from Google back to your code in the page.
There seems to be some confusion on your end about what is sending the request though: In your question title you wrote "NodeJS" (which would imply sending it from the server already) but actually you are sending the request from the script in the browser (which is apparent since you talk about the Firefox network tab, and you use alert which doesn't exist in node.js, plus you talk about a browser extension), so the browser rules apply to you.
See also:
https://medium.com/#dtkatz/3-ways-to-fix-the-cors-error-and-how-access-control-allow-origin-works-d97d55946d9
https://levelup.gitconnected.com/overview-of-proxy-server-and-how-we-use-them-in-react-bf67c062b929
https://www.npmjs.com/package/cors-anywhere
Note: As for why it fails using the Unblock CORS extension with those headers attached (instead of the headers being just ignored), I'm not sure, but it is not relevant because in the request those headers are useless at best and invalid at worst anyway.

AWS API Gateway returns access-control-allow-origin is not allowed by Access-Control-Allow-Headers in preflight response

This may seem like it's been asked a million times but I've tried adding to both my frontend (React) and backend (Lambda with Node.js):
Access-Control-Allow-Headers
Access-Control-Request-Headers
Access-Control-Allow-Methods: 'GET,PUT,POST,DELETE,PATCH,OPTIONS'
But I still get this error:
Access to XMLHttpRequest at 'https://<API-INVOKE-URL>/prod/notes' from origin 'http://localhost:3000' has been blocked by CORS policy: Request header field access-control-allow-origin is not allowed by Access-Control-Allow-Headers in preflight response.
Here's my Lambda code to handle response:
function buildOutput(statusCode, data) {
let _response = {
statusCode: statusCode,
headers: {
"Access-Control-Allow-Origin": "*"
},
body: JSON.stringify(data)
};
return _response;
};
Here's my React code to send the POST request:
createNote(note) {
return API.post("notes", "/notes", {
headers: {
"Authorization": this.state.token,
"Access-Control-Allow-Origin": "*"
},
body: {
userid: this.state.username,
noteid: 'new',
content: 'from frontend'
}
});
I've tested my Lambda function from the console and it works (able to do CRUD to DynamoDB).
I've turned on CORS for my API Gateway resources and deployed the API.
I've tried using PostMan with:
Headers:Content/Type: application/json
Authorization: <MY_TOKEN>
*With and without* Access-Control-Allow-Origin: *
and it works: the request is sent successfully from PostMan to API Gateway results in a new item in my DynamoDB.
Actually adding some data in header converts POST request to OPTIONS.
So that, it will fire to requests:
1) with OPTIONS method
2) After getting a successfull response for OPTIONS request, the actual API call will occur.
To handle CORS you should use this in the backend.
Just to throw some light to the problem. Some browsers will do a "preflight" check to your endpoint. That means that will invoke your endpoint with OPTIONS method before making the POST method call you expect. In AWS, go to API Gateway and create a new resource , check the option to Create Options, that will create the default response headers that you need to add to your endpoint.
CORS requires a direct connection between the client and server. Your browser may be blocking the connection for security reasons.
HTTP versus HTTPS
I'd also try enabling downloads on your browser.
I believe you should also add the bearer to your token in the authorization header like:
'Bearer TOKEN_VALUE'
Thank you, guys. I've upvoted your answers/suggestions. I'm sure they're helpful in most cases. I've figured out why I had that error.
My bad: I have both resources like this:
/notes/ (method: any)
/notes/{noteid} (method: any)
and the Invoke URL is literally <path>/notes/{noteid} (with the {} included in the string) in AWS API Gateway. I was assuming it'd be something like /notes/:noteid
So the frontend code should be like this:
return API.post("notes", "/notes/{noteid}", {...}

GET call from Angular frontend to json-server Access to XMLHttpRequest blocked by CORS policy

i have an angular frontend client on my localhost and trying to make a GET call to a json-server also running on my localhost to get some data due filling a table on a view.
the table still empty and i get this error on chrome console:
"Access to XMLHttpRequest at 'localhost:3000/cilas' from origin 'http://localhost:3001' has been blocked by CORS policy: Cross origin requests are only supported for protocol schemes: http, data, chrome, chrome-extension, https."
added header attribute 'Access-Control-Allow-Origin': '*' but got no result, i've also enabled cross origin resource sharing on google chrome by installing an add-on, server side i just run json-server --watch src/data/document.json so didn't writed any code just put some data on the file document, but the problem seems to be on client side.
//here's the call and the header client side:
headers = new Headers({
'Accept': 'application/json',
'Content-Type': 'application/json',
'Access-Control-Allow-Origin': '*'
});
return this.http.get(pathUrl, { headers: headers }).map(res => res.json());
SOLVED.
my url have to be:
'http://localhost:3000/cilas'
instead of:
'localhost:3000/cilas'
wrongly supposed that http was implicit...

cross domain event source

I am trying to create an EventSource server using nodejs, that will server requests cross domain. I am sending back Access-Control-Allow-Origin header, but the browser (nor Chrome or Opera) won`t let me connect. There are the headers I send back:
this._response.writeHead(200, {
'Content-Type': 'text/event-stream',
'Cache-Control': 'no-cache',
'Connection': 'keep-alive',
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Credentials': 'true'
});
How can I do this the right way?
Regards
Allow-Credentials cannot be used with Allow-Origin set to *.
Consider writing the received Origin-header in your response.
see https://github.com/Yaffle/EventSource - polyfill can be adopted to support CORS for Firefox, Webkit and IE 8+
Try the following block in place of yours. The browser will call one time with OPTIONS and then the request will be made as expected after that.
You won't need the if statement if you have broken out the request methods - but I wanted to give you a full block just in case you're hosting it like the Hello World example did.
if (req.method === "OPTIONS") {
console.log('!OPTIONS');
var headers = {};
// IE8 does not allow domains to be specified, just the *
// headers["Access-Control-Allow-Origin"] = req.headers.origin;
headers["Access-Control-Allow-Origin"] = "*";
headers["Access-Control-Allow-Methods"] = "POST, GET, PUT, DELETE, OPTIONS";
headers["Access-Control-Allow-Credentials"] = false;
headers["Access-Control-Max-Age"] = '86400'; // 24 hours
headers["Access-Control-Allow-Headers"] = "X-Requested-With, X-HTTP-Method-Override, Content-Type, Accept";
res.writeHead(200, headers);
res.end();
}
You get Security Exception (SECURITY_ERR: DOM Exception 18) if you are using cross domain resources. This could be due to :
trying to access local resources via file:// (local files not served via node server) or
trying to access resources from another server that does not allow CORS or
maybe you are testing the page from the local file instead of from the URL served from your node server.
Note: When responding to a credentialed requests request, the server must specify an origin in the value of the Access-Control-Allow-Origin header, instead of specifying the "*" wildcard.
https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS#simple_requests
So:
res.setHeader('Access-Control-Allow-Origin', req.headers.origin)
res.setHeader('Access-Control-Allow-Credentials', 'true')
(server-side)
if client's origin (req.headers.origin) is trusted.
Or simply set {withCredentials: false} (client-side) and use res.setHeader('Access-Control-Allow-Origin', '*') if you don't need it.

Resources