I have a vue.js cli client which consumes an API which resides on Azure (I have developped both client and API).
When I run the client in development mode (npm run serve) my API is correctly responding with Status Code 200. However, when I build the production version (npm run build) and run the dist version locally (serve -s dist), my API call is rejected (400 bad request).
It seems that the build process is doing compiling something differently.
My ApiService.js code snippet:
import axios from 'axios'
const apiURL = 'https://my-api.azurewebsites.net/'
const apiClient = axios.create({
baseURL: apiURL,
withCredentials: false,
headers: {
Accept: 'application/json',
'Content-Type': 'application/json'
}
})
userLogin(credentials) {
return apiClient.post('/login', credentials)
}
This is the diff of the two API calls
When I call the API in production mode the browser reports a cors issue:
Access to XMLHttpRequest at 'https://my-api.azurewebsites.net/login' from origin 'http://www.mysite.ch' 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.
I spent many ours on the web to find a solution, but I was not successful. Any hints are welcomed.
I suspect it is working locally because your local domain is passing the CORS request. Ultimately this is just a CORS configuration issue. Your production domain has not been whitelisted. I'm not sure what your back-end is or how Azure affects it, but you need to whitelist your production domain for API consumption.
This is an example of setting a CORS policy in Express: https://flaviocopes.com/express-cors/
Just make sure you don't allow ALL origins as that is a security risk.
Related
--It was a host error. Issue is solved--
I am using express API.
I have enabled all cors through npm cors package.
like this app.use(cors())
It's working fine when I run it on localhost.
It was also working fine on the actual VPS (server), but suddenly today my API started giving me this error:-
Access to XMLHttpRequest at 'https://apilink' from origin 'https://frontendlink' has been blocked by CORS policy: Request header field authentication is not allowed by Access-Control-Allow-Headers in preflight response.
It's still working fine on my localhost, but now giving above error on actual website.
Below are some of my code block
Thanks in advance
My Axios Instance on frontend
import axios from "axios"
const axiosInstance = axios.create({
headers: {
Authentication: `Bearer ${
somewhere_token ?? null
}`,
},
})
export default axiosInstance
SomeWhere in server.js before all routes
app.use(cors())
I have also tried below solutions in server.js file but none is fixing my issue
// solution 1
app.options('*', cors());
// solution 2
app.use(cors({
origin: "*",
allowedHeaders: "*",
}))
Probably you can fix it by adding * everywhere, but please consider using a reverse proxy to make your request to backend proxy-passed from frontend host as the best practice. I know it's an additional learning curve, but for modern APIs that's probably must have as it allows much more than just solving CORS issue.
Good guide here https://blogs.perficient.com/2021/02/10/nginx-proxy-for-cors/
I'm using axios to make requests to fetch the data from my external API (it's HTTP AWS server with ExpressJS and Nginx). I tested it on my local machine with the web version of my Ionic app and everything is working expected. Also I can fetch data if I'm using my phone's browser.
Same goes with postman, I can fetch data without any problems.
The only place where these requests don't work is the actual device. Looking at the Android Studio console the error is: "Msg: Network Error" (failing to figure out how to get more from axios error object).
I configured CORS following the official Ionic documentation. I've set all needed origins and options (can't use * origin because I have to use credentials with my requests). Express configuration looks like this:
const corsOptions = {
origin: [
'http://localhost:8100',
'http://localhost:8080',
'http://localhost',
'capacitor://localhost',
'ionic://localhost',
],
credentials: true,
optionsSuccessStatus: 200,
exposedHeaders: ["set-cookie"]
}
// Enable preflight requests for all routes
app.options('*', cors(corsOptions));
app.use(cors(corsOptions));
On the client (request example):
try {
const response = await axios('http://my.api.url', {
method: 'get',
withCredentials: true,
headers: {
'Accept': 'application/json'
}
});
const data = response.data;
// Do something with the data
} catch(error) {
console.log(error);
};
I think it has something to do with Capacitor, maybe there is a problem with non-https API (but then the question is why does it work with the web version). I tried disabling credentials for my requests but the error reoccur. Also removing Nginx doesn't seem to change anything.
Update: Also the axios says the request is sent but the server didn't respond.
I sorted it out, I had to do following.
Had to add a SSL to my web server (I used letsencrypt).
Had to add this to capacitor.config.json:
"server": {
"allowNavigation": [
"my.api.url"
]
}
Official Capacitor Documentation - Common Configuration
In my Expo React Native app, I've been trying to fetch data from my Ruby on Rails API but it seems that http connections are not allowed.
All the solutions I've found either add configuration to AndroidManifest.xml in Android and Info.plist in iOS which I can't access, but I'd rather keep development in Expo instead of ejecting. I've tried changing localhost to 127.0.0.1, 10.0.2.2, and my machine's IP as well, but none worked. I've looked at the documentation for configuration with app.json and networking but I can't find anything about configuring App Transport Security within Expo. I'm currently running Expo on android 9.0 Pie.
fetch(`http://localhost:3000/api/v1/trainers`, {
headers: {
Accept: 'application/json',
"Content-Type": "application/json"
},
}).then(res => res.json())
.catch(err => console.log(err));
TypeError: Network request failed
at XMLHttpRequest.xhr.onerror (420454d9-7271-44d5-b…-3a968d130699:48065)
at XMLHttpRequest.dispatchEvent (420454d9-7271-44d5-b…-3a968d130699:53513)
at XMLHttpRequest.setReadyState (420454d9-7271-44d5-b…-3a968d130699:52368)
at XMLHttpRequest.__didCompleteResponse (420454d9-7271-44d5-b…-3a968d130699:52195)
at 420454d9-7271-44d5-b…-3a968d130699:52305
at RCTDeviceEventEmitter.emit (420454d9-7271-44d5-b…-3a968d130699:22482)
at MessageQueue.__callFunction (420454d9-7271-44d5-b…-3a968d130699:22097)
at 420454d9-7271-44d5-b…-3a968d130699:21854
at MessageQueue.__guard (420454d9-7271-44d5-b…-3a968d130699:22051)
at MessageQueue.callFunctionReturnFlushedQueue (420454d9-7271-44d5-b…-3a968d130699:21853)
What domain is your REST api on?
I was having the same problem with fetching from a react native app (running on an emulator) to a node.js/express REST api. I couldn't find a workaround within React.
I found a solution with ngrok (https://ngrok.com). It allows you to expose a specific local domain:port to the outside. With this method I was able to fetch from my app to my REST api.
To be clear, I'm not sure the problem is on React-Native's end. I suspect it was my firewall not allowing the connection to go through. Instead of messing with all of those settings, I simply used ngrok.
I run my project on my Mac OS device and I want to access from another laptop.
the first device gets all responses from the server as well:
http://192.168.1.101:3000/
but another laptop I got this error message:
Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://www.shadyab.com/api/Api/coupons. (Reason: missing token ‘access-control-allow-origin’ in CORS header ‘Access-Control-Allow-Headers’ from CORS preflight channel).
const requestOptions = {
method: 'POST',
headers: { 'Content-Type': 'multipart/form-data',
'Access-Control-Allow-Origin': '*'},
body: JSON.stringify(formData)
};
Add
headers: {'Access-Control-Allow-Origin': '*'}
to your server where the API is fetching from
I think this is something related to your backend sometimes backend only allows some origins and your new front-end domain must be added to Access-Control-Allow-Origin
but sometimes that could be related to the webserver and its configuration needs to be change, for example if you are using Apache .htaccess file must be changed
Assuming you are using cors() in the backend (like in a node server).
Then in your react app, what you can do is setup proxy for the api endpoints.
in the src directory create a file named setupProxy.js. What it does is, create proxies for your api endpoints. What you can do is something like below
setupProxy.js
const { createProxyMiddleware } = require('http-proxy-middleware');
const BACKEND_HOST = process.env.REACT_APP_BACKEND_HOST || 'localhost';
const BACKEND_PORT = process.env.BACKEND_PORT || 8000;
module.exports = function(app) {
app.use(
'/',
createProxyMiddleware({
target: target,
changeOrigin: true,
logLevel: 'debug'
})
);
/**
* You can create other proxies using app.use() method.
*/
};
Note: You do not need to import this file anywhere. It is automatically registered when you start the development server.
And after creating proxies, you should send request to your backend server only specifying the endpoints. Like if you want to send request you should use / instead of http://localhost:8000.
Let me if it works. Thanks
I am trying to create a headless drupal app. i am using drupal 8 as a beckend and react as a front-end. i have created REST services in drupal 8 using core rest services module. the problem is when i am calling the api its giving me error i.e
Fetch API cannot load http://192.168.1.246/headless-react/api/events. 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 403. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
I configured the services.yml file for cors.config but still getting error. can anyone have any idea how to solve it ? thanks
Install the CORS module https://www.drupal.org/project/cors
It will allow you to overcome the error related to cross origin
I am using extension for it. The reason why you get this warning because you called api from another domain. Or you you can use nginx.
https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS
You need to mention what build tools are you using in your front end which uses ReactJS.
Assuming that you are using webpack, you will need to add a proxy in the package.json located at the root directory, like so :
package.json
...
"name": "relay-starter-kit",
"proxy":"<your-base-remote-server-url-here",
"private": true,
...
For instance, if your server is at https://www.myawesomeserver.com, then
"proxy": "https://www.myawesomeserver.com".
In your case, "proxy":"http://192.168.1.246" , should work.
In your application, if you need to access the route, https://www.myawesomeserver.com/home, then you just need to pass the route and webpack will pick up the base url from proxy in package.json
A request for home will look like,
const getHome = async() => {
try{
const raw = await fetch('/home')
const res = await raw.json()
} catch(e) {
console.log(e)
}
}
This is because when you run webpack, it runs the react app on its webpack dev server and for you to communicate with any other server, webpack will have to make a request on your behalf.
If you are not using webpack, this may not be useful for you.