Here Maps Geocode API leads to Cross-Origin error - maps

I use the first example here in order to get the geo coordinates based on an address:
https://developer.here.com/documentation/maps/3.1.15.1/dev_guide/topics/geocoding.html
My JavaScript coding looks almost the same as in the official documentation:
var platform = new H.service.Platform({
'apikey': 'HERE IS MY API KEY'
});
// Get an instance of the geocoding service:
var service = platform.getSearchService();
service.geocode({
q: 'Berlin'
}, (result) => {
result.items.forEach((item) => {
console.log("test");
});
}, alert);
However, when the geocode request is sent, I get the following error:
Access to XMLHttpRequest at '**https://geocode.search.hereapi.com/v1/geocode?xnlp=CL_JSMv3.1.16.1&apikey=[HERE IS MY API KEY]&q=Berlin**' from origin 'null' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
The API key is sent correctly, why do I still get the CORS error?
If I enter the request URL manually in the browser, I get a response and everything is fine.

Yes, the server will help with the issue. I'm here to suggest the alternative.
You can do the geocoding with the HERE Maps REST as well see docs — https://developer.here.com/documentation/geocoding-search-api/dev_guide/topics/endpoint-geocode-brief.html.
Since not all the browsers historically support the CORS (learn more about the CORS — https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS) there is an approach, called JSONP. See some JSONP explanation Here Maps related in the old docs https://developer.here.com/documentation/places/dev_guide/topics/request-cross-domain-js.html.
Eventually the https://www.npmjs.com/package/jsonp npm package could be a good follow up and we can get something like this after installing the package (npm install jsonp --save).
import jsonp from 'jsonp';
jsonp('https://geocode.search.hereapi.com/v1/geocode?q=5+Rue+Daunou%2C+75000+Paris%2C+France&apiKey=my-api-key',
null,
(err, data) => {
if (err) {
console.error(err.message);
} else {
console.log(data);
}
});
This works great from my experience.

If you are testing this code by opening the file in the browser, you may get this error. I suggest using a local server for testing.

Related

How can I fix the "Unhandled Rejection (error): Network error" obtained using axios in React

I'm creating a React Application, and it is hosted on localhost:3000. I want to fetch data from a .NET Core Application hosted on localhost:5001. I'm using axios library to make http requests.
The function in which I make the request is:
async componentDidMount() {
const data = await axios.get("http://localhost:5001/api/gateways");
console.log(data);
}
The obtained Error is "Unhandled Rejection (Error): Network Error".
I tried to test the API with Postman and it works, as well as accessing it from the browser and it works too.
At the same time I tried to consume data from another API, this time hosted on an online server, and it worked perfectly, that means, the problem must be between two applications hosted on the localhost.
I fixed this issue by adding an Access-Control-Allow-Credentials header to HTTP responses in .NET CORE application. This header tells the browser that the server allows credentials for a cross-origin request.
Its necessary modify Configure method at Startup.cs fileadding the following code:
app.Use(async (context, next) =>
{
context.Response.Headers.Add("Access-Control-Allow-Origin", "*");
await next.Invoke();
});
And, it is also necessary modify ConfigureServices method with:
services.AddCors(c =>
{
c.AddDefaultPolicy(options => options.AllowAnyOrigin()
.AllowAnyHeader()
.AllowAnyMethod());
});

Access to XMLHttpRequest blocked by CORS Policy in ReactJS using Axios

I'm setting up stripe connect button in my React Component using Axios. I keep getting this error after redirection
Access to XMLHttpRequest at 'https://connect.stripe.com/oauth/token' from origin 'http://localhost:3000' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: Redirect is not allowed for a preflight request.
Thankyou.js:40 Error: Network Error
at createError (createError.js:16)
at XMLHttpRequest.handleError (xhr.js:87)
I get the code from the url and create a curl request using axios.Post. This is the code in my redirect URL
// Thankyou.js
export default class Thankyou extends Component {
constructor(props) {
super(props);
}
componentDidMount() {
const code = qs.parse(this.props.location.search, {
ignoreQueryPrefix: true
}).code;
const params = {
client_id: "*******************",
client_secret: "**********************",
grant_type: "authorization_code",
code: code
};
axios
.post(
"https://connect.stripe.com/oauth/token",
// apiBaseUrl,
{ params }
)
.then(function(response) {
console.log(response);
})
.catch(function(error) {
console.log(error);
});
console.log(code);
}
render() {
return (
<div>
<h2>Thank you for connecting with us!</h2>
</div>
);
}
}
There is nothing wrong with your code, but most likely the API endpoint the code trying to reach is not setup for JavaScript web app. CORS policy is set on the server-side and enforced primarily on the browser-side.
The best way to work around is to use Stripe's JavaScript solution such as Strip React Elements or Stripe.js.
A hacky way to get around CORS would be setting up Reverse proxy with solutions such as NGINX. For example, you can use the following nginx configuration:
server {
listen 8080;
server_name _;
location / {
proxy_pass http://your-web-app:2020/;
}
location /stripe/ {
proxy_pass https://connect.stripe.com/;
}
}
By doing so, all the API calls to Stripe.com could be through /stripe under your web app's URL. For example, calling http://yourapp/stripe/oauth/token would be same as calling https://connect.stripe.com/oauth/token
That being said, the second solution is hacky and Stripe may decide to block your reverse proxy server.
basically you need to talk to whoever is hosting this https://connect.stripe.com/oauth/token to enable CORS (Cross Origin Resource Sharing )
It is a security measure implemented by most standard browsers to stop unwanted requests to your backend
It's probably because Stripe doesn't provide JavaScript client so you either have to use your own server proxy or use something like "https://cors-anywhere.herokuapp.com/https://connect.stripe.com/oauth/token"
I hope this answer would be useful to new users:
This issue can be easily fixed by using an annotation in your spring boot rest controller class.
Something like below (also ref screenshot):
#CrossOrigin(origins = "http://localhost:4200")
Explicitly mention the react JS server URL that is causing this issue.
Now after adding above annotation (with your react JS server URL) the browser will allow the flow.
All the best.
Learn about CORS
Think about it, there is anything wrong with your axios.post request, it's successfully contacting the server. But there is one more thing to do before the server let you execute or manipulate it's files.
For security reasons, browsers restrict cross-origin HTTP requests initiated from within scripts. For example, XMLHttpRequest and the Fetch API follow the same-origin policy.
So your cross-origin request and the server Cross-Origin Resource Sharing (CORS) have to match.
How do you solve it?
Depending on your server and the server side programming language your are implementing, you can configure the different parameters to handle your CORS.
For example, you can configure that the only allowed methods will be:
GET HEAD
So if someone try to axios.post to your server with a different method like POST, it will return an error like this:
Access to XMLHttpRequest at 'https://connect.stripe.com/oauth/token' from origin 'http://localhost:3000' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: Redirect is not allowed for a preflight request.
Thankyou.js:40 Error: Network Error
at createError (createError.js:16)
at XMLHttpRequest.handleError (xhr.js:87)
Resources:
https://www.w3.org/TR/cors/
https://developer.mozilla.org/en-US/docs/Web/Security/Same-origin_policy
https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS
I would suggest reading through this site: https://stripe.com/docs/recipes/elements-react
It gives specific instructions straight from stripe on using their API with react. Good luck!

Firebase CORS issue

I built a react app and I have deployed it on firebase. I have been getting this error whenever user searches.
Failed to load https://food2fork.com/api/search?key=0882376145a8bcae6c3cee&q=fish&count=50: Redirect from
'https://food2fork.com/api/search?key=0882376145a8107c5946c3cee&q=fish&count=50' to
'https://www.food2fork.com/api/search
key=0882376145a8bcae390107c5946c3cee&q=fish&count=50'
has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is
present on the requested resource. Origin 'https://recipe-finder-26e0e.firebaseapp.com' is therefore not allowed access.
As I am new to this one, I am unable to figure out how to enable CORS in firebase which I think is the problem. If anyone can tell me how to enable CORS I would be grateful Thank you.
Edit: Source code link --> https://github.com/AdiBev/Recipe-Finder
Update: I didn't understand in the beginning that CORS needs to be handled by back end. Thanks to #Ben. Ayoub for explaining it to me.
If it helps for any others like me who got same problem I found a great article and some proxies are mentioned there.
link ---> https://gist.github.com/jesperorb/6ca596217c8dfba237744966c2b5ab1e
In addition to Ben. Ayoub's solution it could be worth you looking into HTTPS Callable functions if it's only your app trying to communicate with the Function and it's not part of a wider external API.
They work similar to HTTPS endpoints but get rid of the headaches of CORS.
import * as functions from 'firebase-functions';
export const listener = functions.https.onCall((data, context) => {
if (data) {
throw new functions.https.HttpsError('invalid-argument');
}
return {
some: 'json',
};
}
You don't need to use the request and response parameters like in the HTTP Endpoint Cloud Function.
It accepts JSON as it's context and returns a simple JSON object.
Edit
To answer your original question, the cloud functions can make use of CORS
import * as functions from 'firebase-functions';
const cors = require('cors')({ origin: true });
export const listener = functions.https.onRequest((req, res) => {
cors(req, res, () => {
return;
});
// cloud function logic
res.json({ some: 'json' });
});

Angular $http.post not working, works using postman

I've created an Ionic app which calls an API to post the user's current location.
The request works as follows:
POST: http://mywebsite.com/api/Patients/AddLocation/17
with body:
{
"Latitude": 51.3753786,
"Longitude": -0.0833691
}
However, the following code in my Ionic app does work:
$http.post('http://mywebsite.com/api/Patients/AddLocation/' + $scope.id, data)
.success(function () {
console.log('Updated location');
})
.error(function (error) {
console.log('Error updating location');
console.log("Error: " + error);
});
In which 'data' is the same as the body above.
Any ideas why this isn't working?
UPDATE:
Here's a couple of screenshots of the network request:
Network request available at imgur RWNDF.png
Postman request
It happens if you have not enabled cors in your server.
enable cors in you server.
even if you dont enable cors,
get method will work peerfectly if you have enabled cors using any extension in chrome.
It's because of CORS. Enable cros from the server end and the a header will be set in HTTP Access-Control-Allow-Origin: * .
If your server app is an expressjs app, use below code to enable CORS
var cors = require('cors');
.....
app.use(cors());
Else use chrome extension Allow Cross Origin Request
This should solve the problem
After comparing this to a sister app which uses the same API and works, the only difference I could see was that a few of the plugins were different.
To remedy this I deleted the plugins folder and the platforms folder, re-added android and just the plugins I need, it now works. I guess it's maybe some bug I created by using the wrong mixture of plugins.
A very unsatisfying answer, but all requests work now!

Load external json in react-native with fetch

I am trying to load external data with fetch into a react-native mobile app. I have tried with different sources and mostly I get an error message saying the network can't be found.
For instance I have tried with the following two sources.
http://facebook.github.io/react-native/movies.json (does not work)
https://raw.githubusercontent.com/facebook/react-native/master/docs/MoviesExample.json (works)
componentDidMount(){
var REQUEST_URL = 'http://facebook.github.io/react-native/movies.json';
fetch(REQUEST_URL).then((response) => {
console.log(response);
if(response.ok) {
console.log('Response OK');
} else {
console.log('Network response was not ok.');
}
})
.catch((error) => {
console.log('There has been a problem with your fetch operation: ' + error);
})
.done();
}
I am testing in IOS simulator on my MacBook.
I also tried to get json data from my WordPress site, with the latest version of the WP REST API plugin installed. Also this returned a can't find network error.
I am really stuck on this one.
That’s caused by apple’s security rule, http protocol is restricted(you are sending a http request).
If you need communication in http protocol, there are two solutions(all related to info.plist):
1: Just like what the quick start project does, add the domain name of server:
2: Add a new rule: “Allow Arbitrary Loads”. don’t forget set the value to “YES”.

Resources