React CORS with URL Param despite setting CORS policy on - javascript

So I am trying to make a fetch request to get data before component loads using componentWillMount, but it keeps throwing error
Access to fetch at 'http://localhost:5000/mine/1/user_list' from origin 'http://localhost:3000' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: It does not have HTTP ok status.
Now I did try all solution proposed in other related question. Some of the things that I tried was setting 'Allow-CORS' param in the header. Also I have Google chrome tool that turns the CORS on and it is already on. Apart from that I also have tried keeping parameter in the fetch request with the mode.
But it is not working. Interesting thing is that if I try with constant URL (for example, http://locahost:5000/maintenance/company/fetch) the request goes through fine without any issue. However, when I use custom path URL as shown below (http://localhost:5000 + "mine/" + activeSite + "/user_list";) then issue starts. I have attached small snippet of the code for your reference.
My backend is in Python3 flask-restplus. It doesn't receive the request on backend. Error is thrown before even it makes fetch request. My controller has no such policy on for CORS on backend. But I assume if other request works fine in the app this should work fine without having that policy in the backend. Also I tested function with Swagger-UI and it works fine.
import React, { Component } from "react";
import Select from "react-select";
import { serverConst } from "../constants/system";
import { getAuthHeader } from "../helper/authHeader";
class TaskForm extends Component {
constructor(props) {
super(props);
this.state = {
assigned: "",
assigner: [],
reporter_list: [],
operationSucceed: false,
error: ""
};
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
componentWillMount() {
let activeSite = localStorage.getItem("activeMinesite");
if (activeSite) {
const request_url = serverConst.SERVER_URL + "mine/" + activeSite + "/user_list";
fetch(request_url, {
method: "GET",
mode: "cors",
headers: getAuthHeader()
}).then(response => {
response.json().then(json => {
console.log(response);
});
});
}
}

Related

How to bypass CORS policy when sending get/post request from React JS?

From my React JS app , I need to fetch data from servers in other domains.
However, I am prevented by CORS policy and not able to fetch the data.
Let us assume that my React app is running on localhost:3000 during the development.
I want to make get/post call to another server running on http://myserver.com
The URL through which I want to fetch the data is http://ext-server.com/data/records?name=xyz
I have installed http-proxy-middleware thru npm and using it in my react app.
Created a setupProxy.js file under src folder with below content :
const { createProxyMiddleware} = require("http-proxy-middleware")
module.exports = app => {
app.use(
createProxyMiddleware('/data/records' , {
target:'http://ext-server.com',
changeOrigin: true
})
)
}
On the landing page of my react app (firstpage.js) when http://localhost:3000 is hit , I have added below piece of code to the button event that makes the get call to the http://ext-server.com
getTheData() {
let url = "http://ext-server.com/data/records?name=" + encodeURIComponent(this.state.name);
axios.get(url,
{
headers: {
"Content-Type":"application/json;charset=UTL-8",
"Access-Control-Allow-Origin": "*",
Accept: "application/json",
},
baseURL: 'http://ext-server.com'
}
).then((response) => {
console.log(response["access_token"]);
}).catch(error) => {
console.log("Error: ", error)
}).then(function () {
console.log("always call it")
});
}
In the package.json , I have added :
"proxy": "http://ext-server.com",
"homepage":"http://localhost:3000",
But I am still getting below error:
Access to XMLHttpRequest at 'http://ext-server.com/data/records?name= ' from origin 'http://localhost:3000' has been blocked by CORS policy.
Is there anything that I am missing here ? what is the correct way to use this http-proxy-middleware?
Any help will be very useful!
Thanks
As you can see from MDN the "Access-Control-Allow-Origin": "*" header is a response type header, this means that it should go to in your server response. Also I advise you to not use the * symbol, instead I would rather match it with the origin header in your Request.
The CORS policy is one and only administered by the web server and its settings. To allow CORS requests it has to be implemented on server side. No chance to do it from your client application.
Basically its just a header setting (below example for NodeJS):
res.header("Access-Control-Allow-Origin", "*")
Sending that header will allow requests from every domain.

React API Fetch fail

I am trying to create a site where I will consume a web-api and display "users" on the site. I have an API-key that I have to put in the header as "x-api-key".
This is my code at the moment:
import React, { Component } from 'react';
import './App.css';
class App extends Component {
constructor(props) {
super(props);
this.state = {
isLoaded: false,
items: []
}
}
componentDidMount() {
const myHeaders = new Headers();
myHeaders.append('x-api-key', 'KEY_HERE');
myHeaders.append('Content-Type', 'application/x-www-form-urlencoded');
myHeaders.append('cache-control', 'no-cache')
fetch('URL_HERE', {
method: 'GET',
headers: myHeaders,
async: true,
})
.then(res => res.json())
.then(json => {
this.setState({
isLoaded: true,
items: json,
})
});
}
render() {
var{isLoaded, items} = this.state;
if(!isLoaded) {
return <div>Loading...</div>;
}
else{
return (
<div className="App">
<ul>
{items.map(item => (
<li key={item.id}>
Name: {item.name} | Id:{item.id}
</li>
))};
</ul>
</div>
);
}
}
}
export default App;
The problem is I get these error messages in the console:
Failed to load http://URL/users: Response for preflight does not have
HTTP ok status.
Uncaught (in promise) TypeError: Failed to fetch
When I tried making a GET call in Postman I succeeded. So I suppose the problem is that the api-key doesnt get implemented in the header properly.
Appreciate the help, please let me know if there is anything else you need to know!
You need to remove below line from your code and after that, you need to handle OPTIONS method from server-side.
myHeaders.append('cache-control', 'no-cache')
You are getting this error because you are adding a header with 'x-api-key'. you have made the request complex. This requires the browser to make a preflight OPTIONS request to ask for permission to send the complex request.
The server you are making the request to is responding saying that OPTIONS requests are not allowed to that URL
You will need to modify the server and handle OPTION method properly so that it responds appropriately to the preflight CORS request.
You are not getting this error in postman because Postman doesn't need to make a preflight request.
Try to use axios if you want to fetch data using api.
It can be used at client side and server side as well and very much easy as well.
Here is the GitHub repo for your guide.
https://github.com/axios/axios

XMLHttpRequest cannot load http://abc.mydomain.org/data/todo.js

I want to use /data/todo.js file in my reactjs component. I have used axios http request to get this data in my react component i.e.,
import React, { Component } from 'react';
import axios from 'axios';
class TodoList extends Component {
componentWillMount() {
var config = {
headers: {
"Access-Control-Allow-Origin": "http://localhost:8080/",
"Access-Control-Allow-Credentials": true
}
};
axios.get('http://abc.mydomain.org/data/todo.js', config)
.then((response) => {
console.log(response);
}).catch((error) => {
console.log(error)
})
}
render() {
return (
<div className="todo-list"></div>
);
}
}
export default TodoList;
It gives an error
XMLHttpRequest cannot load http://abc.mydomain.org/data/todo.js. Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:8080' is therefore not allowed access.
You are trying to access a cross-origin HTTP request from you application, which is by default blocked by the browser.
To access the resource, Cross-Origin Resource Sharing (CORS) should be enabled at the application you are trying to access (In your case http://abc.mydomain.org)
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. This means that a web
application using those APIs can only request HTTP resources from the
same domain the application was loaded from unless CORS headers are
used.
You can check more on this here

Getting tweets with React

I'm using the Twit package to pull tweets. I keep getting error 400, and
Failed to load https://api.twitter.com/1.1/statuses/user_timeline.json?screen_name=twitterdev&count=10: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:3000' is therefore not allowed access. The response had HTTP status code 400. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
The bulk of this was able to work with vanillajs, but once I imported into React, I've gotten these errors. How do I fix this? I've taken out the API keys for security.
import React, { Component } from 'react';
import Twit from 'twit';
export default class Twitter extends Component {
componentDidMount() {
const T = new Twit({
consumer_key: '...',
consumer_secret: '...',
access_token: '...',
access_token_secret: '...'
})
let params = {
screen_name: 'twitterdev',
count: 10
};
function getData(err, data, response) {
let tweet = data;
for (var i = 0; i<tweet.length; i++) {
console.log(tweet[i].text);
console.log();
}
}
T.get('statuses/user_timeline', params, getData);
}
render() {
return(
<div></div>
)
}
}
The Twitter API does not support CORS requests. That's what you are trying to do. Accessing API from a different domain. You'll have to create a bespoke url at your local server that proxies the request to the Twitter
API.

CORS issue with ASP.net Identity

I am working on an angular.js project with one of my friends, and we are running into a specific CORS (cross origin request) issue. The server is a Microsoft ASP.NET restful API, and I am using angular.js with Node.js.
We enabled CORS on the server side, and are able to get responses for everything else, accept the user login, which we are using ASP.NET Identity with. We always get the same error which I will post bellow, as well as the POST from the Client side. So basically my question is, does any one have an idea on how to fix this? Thanks!
XMLHttpRequest cannot load http://lectioserver.azurewebsites.net/api/v1/accounts/login. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'localhost' is therefore not allowed access. The response had HTTP status code 400.
function login(username, password) {
var innerconfig = {
url: baseUrl + "/api/v1/accounts/login",
data: {
username: username,
password: password,
grant_type: "password"
},
method: "POST",
headers:
{
'Accept': 'text/json'
}
};
return $http(innerconfig).then(onSuccess, requestFailed);
function onSuccess(results) {
if (results && results.data) {
$rootScope.access_token = results.data.access_token;
return results.data;
}
return null;
}
}
Try to set the content-type in the headers, this might fix the issue
headers: { 'Content-Type': 'application/x-www-form-urlencoded' }
This usually happens because app that provides you token starts before CORS initiates.
Fixing it is very easy. You just need to go to IdentityConfig.cs and inside that there is function called as
public static ApplicationUserManager Create
(IdentityFactoryOptions<ApplicationUserManager> options, IOwinContext context)
Insert this following line of code there
context.Response.Headers.Add("Access-Control-Allow-Origin", new[] { "*" });
This will enable CORS for Token request.
But problem is when we do this other normal requests will start throwing error since we have granted access origin * twice. Once in identiy and other in cors.
if you run into this error use this if statement on cors code in identity config you just pasted.
if(context.Request.ContentType == "text/plain")

Categories

Resources