Error when calling API in Front using React - reactjs

I have an error that shows when I try to click button to subscribe. This is the error message in browser console:
Access to fetch at 'https://api.exhia.com/api/accounts/addaccount' from origin 'http://localhost:3000' 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 an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
This the the code example that handle the click:
handleFormSubmit(event) {
event.preventDefault();
this.setState({ msg: 'checked' });
const validation = this.validator.validate(this.state);
this.setState({ validation });
this.submitted = true;
if (
this.state.checked === true &&
validation.subConfirm_pwd.isInvalid === false
) {
fetch(`${API}/api/accounts/addaccount`, {
method: 'POST', // 'GET', 'PUT', 'DELETE'
body: JSON.stringify({
email: this.state.sub_mail,
password: this.state.sub_pwd,
acceptCGU: this.state.checked,
}),
headers: {
'Content-Type': 'application/json;charset=utf-8',
Accept: 'application/json',
},
})
.then(res => res.json())
.....
I am working on prod to handle this issue, this is my webpack.config:
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
const ManifestPlugin = require('webpack-manifest-plugin');
const UglifyJsPlugin = require('uglifyjs-webpack-plugin');
var OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin');
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
module.exports = {
mode: 'production',
entry: './src/index.js',
output: {
path: path.resolve(__dirname, 'build'),
publicPath: '/',
filename: 'bundle.js'
},
devServer: {
contentBase: path.join(__dirname, './build'),
compress: true,
port: 3000,
historyApiFallback: true,
},
performance: {
hints: false,
maxEntrypointSize: 512000,
maxAssetSize: 512000
},
module: {
rules: [
{
test: /\.(css|sass|scss)$/,
use: [
MiniCssExtractPlugin.loader,
{
loader: 'css-loader',
options: {
sourceMap: true,
importLoaders: 2
},
},
{
loader: 'sass-loader',
options: {
sourceMap: true,
},
},
],
},
{
test: /\.(js|jsx)$/,
exclude: /node_modules/,
use: {
loader: "babel-loader"
}
},
{
test: /\.(png|svg|jpg|gif)$/,
use: ["file-loader"]
},
{
test: /\.(woff(2)?|ttf|otf|eot|svg)(\?v=\d+\.\d+\.\d+)?$/,
use: [
{
loader: 'file-loader',
options: {
name: '[name].[ext]',
outputPath: 'fonts/'
}
}
]
}
]
},
//remove comments from JS files
optimization: {
minimizer: [
new UglifyJsPlugin({
uglifyOptions: {
output: {
comments: false,
},
},
}),
new OptimizeCSSAssetsPlugin({
cssProcessorPluginOptions: {
preset: ['default', { discardComments: { removeAll: true } }],
}
})
],
},
plugins: [
new MiniCssExtractPlugin({
filename: "[name].css"
}),
new ManifestPlugin(),
new CleanWebpackPlugin(),
new HtmlWebpackPlugin({
template: path.resolve('./public/index.html'),
}),
]
};
I am not sure where the bug comes from. How can I fix it?

http://localhost:3000 has been blocked by CORS policy so All you need to do is add an HTTP header to the server which serves your API. That means changing the API.
In your case this is either ( fatboar.extia.com ) or (api.exhia.com) - I can't tell which as you seem to use them interchangeably in your question / comments.
This site provides details on how to do that: https://enable-cors.org/server.html - should you need further guidance I would investigate how to add header for your particular platform. You should be able to see the header coming back in a tool like Postman (https://www.getpostman.com/) - I would explore the API first with that to check the header, then proceed with your code in the browser.
1) Access-Control-Allow-Origin: http://localhost:3000
Note. When you move to production, you may need to change the above to match the server making the call. So for example, locally at the moment you are hosting the app on localhost:3000. When you move to production assuming you are hosting on blah.com, your access control header would also need to change.
2) Access-Control-Allow-Origin: http://blah.com
Do not be tempted by answers suggesting a wild card e.g.
3) Access-Control-Allow-Origin: *
This will allow any authorised person to access the API from any domain, which is likely not what you want. So any site can make a request to your site on behalf of their visitors and process its response.

This is because you are trying to call a service which is running in different server.
More on cors issue
If it is for development environment, you should be using some kind of proxy for example webpack Dev server proxy
Another option is to disable the cors check in browser by some kind of plug in, simple search in chrome app store will give you many plug ins.

Related

Reactjs v17.0.2 showing blank white screen on chrome browser but its completely fine on firefox browser

I am using Webpack as my module bundler for my Reactjs application. Using spring boot as a backend service. It's completely fine on the Firefox browser both in the development and production server. You can check the production version from here:
https://fullstackapp.io
But it's not working on chrome browser its showing completely a blank white page like this both in the production and development environment. How can I overcome with this situation?
My wepback.config.js is:
const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");
module.exports = {
mode: "development",
entry: "/src/index.jsx",
output: {
path: path.resolve(__dirname, "build"),
publicPath: '/',
filename: "bundle.js",
},
module: {
rules: [
{
test: /\.(js|jsx)$/,
exclude: /node_modules/,
use: ["babel-loader"]
},
{
test: /\.css$/,
use: ["style-loader", "css-loader"]
},
{
test: /\.(png|jpg|jpeg|gif|svg|ico|ttf|eot|woff)$/,
exclude: /node_modules/,
use: ["file-loader"]
},
]
},
resolve: {
extensions: [".jsx", ".js"]
},
devServer: {
port: 3000,
static: {
directory: path.join(__dirname, 'public'),
},
hot: true,
historyApiFallback: true,
proxy: {
'/api': {
target: 'http://localhost:8080',
secure: false
}
},
},
watchOptions: {
ignored: /node_modules/
},
plugins: [
new HtmlWebpackPlugin({
hash: true,
title: "Hot Module Replacement",
template: "/public/index.html"
})
]
}
Showing error:
Finally I solved my problem. The problem is actually happened because of this code which I wrote in my App.js file. I removed it and it works.
useEffect(() => {
window.onload = () => {
setTimeout(() => {
setPageLoad(false);
}, 30);
}
window.addEventListener("popstate", () => {
setPageLoad(true);
window.location.reload();
})
},[])
I used it because, I need some times to set my route when user use browser hard reload or navigate backward or forward using browser button. I removed it and solved it in another way. And now it's working completely fine.

React webpack proxy cors issue when calling the api

Error in a reactjs , when connecting to the backend end via webpack proxy, the url doesnt work , gives 404 not found even tho the endpoint is correct. working with typescript
and I'm using axios to get my data in the httpservice page.
devServer: {
port: 8083,
historyApiFallback: true,
contentBase: paths.public,
proxy: {
"/api": "http://localhost:8083",
},
headers: {
"Access-Control-Allow-Origin": "*",
https: true,
},
},
mode: "development",
entry: paths.entry,
resolve: {
extensions: [".js", ".jsx", ".ts", ".tsx", ".json"],
alias: {
src: paths.src,
assets: paths.assets,
},
},
output: {
filename: "[name].[chunkhash:8].js",
publicPath: "/",
},
module: {
rules: [
{
test: /\.m?js/,
resolve: {
fullySpecified: false,
},
},
{
test: /\.tsx?$/,
use: "ts-loader",
},
{
test: /\.(png|jpg|gif|svg)$/i,
type: "asset/resource",
},
],
},
plugins: [
new HtmlWebpackPlugin({
inject: true,
template: paths.html,
}),
],
and on the fetch side I call like so
import http from "./httpServices";
const apiEndpoint = "/api/item";
function itemUrl(id) {
return `${apiEndpoint}/${id}`;
}
export const getItemsFromApi = () => {
return http.get(apiEndpoint);
};
you forgot to add pathRewrite: { '^/api': '' }.
The proxy is not overwriting the api endpoint. pathRewrite will replace /api with the target
proxy: {
"/api": {
target: "http://localhost:8083/",
pathRewrite: { "^/api": "" },
},
},
DevServer Documentation: https://webpack.js.org/configuration/dev-server/#devserverproxy

No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:8080' is therefore not allowed access [duplicate]

This question already has answers here:
Why doesn't adding CORS headers to an OPTIONS route allow browsers to access my API?
(36 answers)
How does the 'Access-Control-Allow-Origin' header work?
(19 answers)
Closed 4 years ago.
I'm calling Drupal API from React JS and getting the following error :
Failed to load http://l-and-d.dd:8083/node?_format=json: 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.
I have already allowed all the requests on my Drupal server and I'm still getting this error.
I think the error is on the client side.
I have also added the headers on webpack.config.js file
Here is webpack.config.js file
const path = require('path')
module.exports = {
entry: './src/app.js',
output: {
path: path.join(__dirname, 'public'),
filename: 'bundle.js'
},
module: {
rules: [{
loader: 'babel-loader',
test: /\.js$/,
exclude: /node_modules/
}, {
test: /\.scss$/,
use: [
'style-loader',
'css-loader',
'sass-loader'
]
},
{
test: /\.(eot|svg|woff|woff2|ttf|png|svg|jpg|jpeg|bmp|gif|pdf)$/,
use: [
'file-loader'
]}
]
},
devtool: 'cheap-module-eval-source-map',
devServer: {
contentBase: path.join(__dirname, 'public'),
historyApiFallback: true,
headers: {
'Access-Control-Allow-Origin' : '*'
}
}
}
I have also tried adding the custom headers in my code but that too didn't work,
here is the API calling code :
axios({
method: 'POST',
url: 'http://l-and-d.dd:8083/node?_format=json',
data: node,
headers: {'Access-Control-Allow-Headers': '*',
'Access-Control-Allow-Origin': '*',
'Access-Control-Expose-Headers':'*',
'Content-Type':'application/json',
'Accept':'application/json',
'X-Custom-Header': '*' }
}).then((res) => {
console.log(res)
}).catch((err) => {
console.log(err)
})
This is due to your file is in different port and your reactjs is running in different port this issue will automatically be resolved once the application is deployed in the same environment or if u need to fix it now you can add this extension in your browser link
Try installing the CORS module for drupal and set the value in the cors module to "*". https://www.drupal.org/project/cors

webpack dev server not allowing POST fetch request - react app

I am developing my first webapack-react app using webpack-dev-server, however I am running into issues sending POST requests to my flask backend api as I keep getting a 400 bad request error. Here is my post request:
fetch('/api/login', {
method: 'post',
headers: {'Content-Type':'application/json'},
body: JSON.stringify({"first_name": "name"})
});
If I tweak the above to a GET request (and remove body), the request goes through fine and I the api returns data.
Digging a little deeper, it seems as though webpack-dev-server doesn't permit POST requests - have I understood that correctly and is there a workaround?
Here is my webpack dev configuration:
const merge = require('webpack-merge');
const common = require('./webpack.common.js');
const webpack = require('webpack');
module.exports = merge(common, {
mode: 'development',
devtool: 'inline-source-map',
devServer: {
contentBase: './dist',
host:'0.0.0.0',
hot: true,
historyApiFallback: true,
proxy: {
'/api': {
target: 'http://flaskapp:5090',
pathRewrite: {'^/api': ''},
secure: false,
}
},
},
plugins: [
new webpack.HotModuleReplacementPlugin()
]
});
This is by no means the accepted answer. I'm just sharing my Webpack file to how I got it to work.
Here is my webpack.config file. I had the same issue the other day with making fetch requests with POST. However, I looked online to see if I could remove the /api from my fetch requests so I tried the rewrite module and it didn't work for me so I just removed it. In my fetch requests if I wanted to fetch something for example it would be /api/signup for example and my fetch worked. I also set up my proxy in webpack not in package.json
const webpack = require('webpack');
const path = require('path');
const nodeExternals = require('webpack-node-externals');
const HtmlWebPackPlugin = require('html-webpack-plugin');
var browserConfig = {
devServer: {
historyApiFallback: true,
proxy: {
"/api": "http://localhost:3012"
}
},
entry: ['babel-polyfill', __dirname + '/src/index.js'],
output: {
path: path.resolve(__dirname + '/public'),
filename: 'bundle.js',
publicPath: '/'
},
module: {
rules: [
{
test: /\.jsx?$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
query: {
presets: ['react', 'env', 'stage-0']
}
}
}
]
},
plugins: [
new HtmlWebPackPlugin({
template: './public/index.html',
})
]
}
var serverConfig = {
target: 'node',
externals: [nodeExternals()],
entry: __dirname + '/server/main.js',
output: {
path: path.resolve(__dirname + '/public'),
filename: 'server.js',
publicPath: '/'
},
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
query: {
presets: ['react', 'env', 'stage-0']
}
}
}
]
}
}
module.exports = [browserConfig, serverConfig]

webpack dev server CORS issue

I am using webpack-dev-server v1.10.1 to boost up my Redux project and I have the options below:
contentBase: `http://${config.HOST}:${config.PORT}`,
quiet: false,
noInfo: true,
hot: true,
inline: true,
lazy: false,
publicPath: configWebpack.output.publicPath,
headers: {"Access-Control-Allow-Origin": "*"},
stats: {colors: true}
In the JS, I am using request from superagent to generate a HTTP GET call
request
.get(config.APIHost + apiUrl)
.set('Accept', 'application/json')
.withCredentials()
.end(function (err, res) {
if (!err && res.body) {
disptach(() => {
return {
type: actionType || GET_DATA,
payload: {
response: res.body
}
}
});
}
});
But I got the CORS error:
XMLHttpRequest cannot load http://localhost:8000/api/getContentByType?category=all. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:5050' is therefore not allowed access
Any suggestion to resolve this? Thanks a lot
Another way to work around it is to directly add the required CORS headers to the dev server:
devServer: {
...
headers: {
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Methods": "GET, POST, PUT, DELETE, PATCH, OPTIONS",
"Access-Control-Allow-Headers": "X-Requested-With, content-type, Authorization"
}
}
Doc links
Webpack dev server
Access-Control-Allow-Headers
Access-Control-Allow-Methods
Access-Control-Allow-Origin
With webpack-dev-server 1.15.X you can use this configuration in your config file:
devServer: {
contentBase: DIST_FOLDER,
port: 8888,
// Send API requests on localhost to API server get around CORS.
proxy: {
'/api': {
target: {
host: "0.0.0.0",
protocol: 'http:',
port: 8080
},
pathRewrite: {
'^/api': ''
}
}
}
},
With this example you will redirect all calls from http://0.0.0.0:8888/api/* to http://0.0.0.0:8080/* and CORS solved
Had the same issue, but my api was on a https protocol (https://api....). Had to start the server with https and use https://localhost:8080
devServer: {
https: true,
headers: {
"Access-Control-Allow-Origin": "*",
},
// ....
}
You're running your JavaScript from localhost:5050 but your API server is localhost:8000. This violates the same origin policy, so the browser disallows it.
You can either modify your API server so that CORS is enabled, or follow the instructions on the webpack-dev-server page under "Combining with an existing server" to combine asset serving with webpack-dev-server and your own API server.
There are 2 solutions for this. first one is setting up proxy on the client side, second one is setting CORS on the server. CORS is server issue, server does not allow access from different source. Even using different ports is considered to be different source
First Solution
IN your backend code, you have to set this headers: this is example of in express node.js
app.use((req, res, next) => {
res.setHeader("Access-Control-Allow-Origin", "*");
res.setHeader(
"Access-Control-Allow-Methods",
"OPTIONS, GET, POST, PUT, PATCH, DELETE"
);
res.setHeader("Access-Control-Allow-Headers", "Content-Type, Authorization");
next();
});
Second Solution:
in webpack config.js, if you want to pass any variable, we export
module.exports=function(env){
return {}}
instead of
module.exports={}
we inject this env through the script.
"dev-server": "webpack-dev-server --env.api='https://jsonplaceholder.typicode.com/users'",
now webpack has access to this env. in webpack.config.js
module.exports = function ({
api = "https://jsonplaceholder.typicode.com/users",
}) {
return {
entry: { main: "./src/index.js" },
output: {
path: path.resolve(__dirname, "public"),
filename: "[name]-bundle.js",
publicPath: "/",
},
mode: "development",
module: {
rules: [
{
loader: "babel-loader",
test: /\.js$/,
exclude: [/node_modules/],
},
{
// Load other files, images etc
test: /\.(png|j?g|gif|ico)?$/,
use: "url-loader",
},
{
test: /\.s?css$/,
use: ["style-loader", "css-loader", "sass-loader"],
},
],
},
//Some JavaScript bundlers may wrap the application code with eval statements in development.
//If you use Webpack, using the cheap-module-source-map setting in development to avoid this problem
devtool: "cheap-module-eval-source-map",
devServer: {
contentBase: path.join(__dirname, "public"),
historyApiFallback: true,
proxy: {
"/api": {
changeOrigin: true,
cookieDomainRewrite: "localhost",
target: api,
onProxyReq: (proxyReq) => {
if (proxyReq.getHeader("origin")) {
proxyReq.setHeader("origin", api);
}
},
},
},
},
};
};

Resources