webpack dev server CORS issue - reactjs

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);
}
},
},
},
},
};
};

Related

Axios call getting blocked due to CORS error

I have a react application with server side rendering using Express server . I want to make a POST request using axios but it is getting blocked with CORS error :
"Access to XMLHttpRequest at 'https://xyz/abc' from origin 'http://localhost:4249' 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 have tried after adding allow origin headers and cors module in my server call but that didn't work
import cors from "cors";
const server = express();
server.use((req, res, next) => {
res.header("Access-Control-Allow-Origin", "*");
res.header(
"Access-Control-Allow-Methods",
"OPTIONS, GET, POST, PUT, PATCH, DELETE"
);
res.header("Access-Control-Allow-Headers", "Content-Type, Authorization");
next();
});
server.use(express.static("dist"));
server.use(cors());
Here is the axios request :
const headers = {
Accept: "application/json",
"x-ms-version": "2019-07-11",
Authorization: token,
"x-ms-date": date,
"x-ms-documentdb-isquery": true,
"Content-Type": "application/query+json",
"x-ms-documentdb-query-enablecrosspartition": "true",
"cache-control": "no-cache",
"Access-Control-Allow-Origin": "*",
};
useEffect(() => {
axios
.post(
"https://xyz/abc",
data,
{
headers: headers,
}
)
.then(function (response) {
setres(response.data);
})
.catch(function (error) {
console.log(error);
});
}, []);
Webpack Config:
module.exports = {
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: "babel-loader",
},
},
{
test: /\.(sass|css|scss)$/,
use: ["style-loader", "css-loader"],
},
],
},
};
I have encountered this problem before, and this is just what I did:
app.js (backend)
server.use(cors({
origin: '<YOUR_FRONTEND_URL_PATH>',
methods: 'GET,HEAD,POST,PUT,DELETE',
preflightContinue: false,
credentials: true
}));
axios request:
const resp = await axios.post(
apiUrl,
params,
{
withCredentials: true,
timeout: 10000
}
);

Error when calling API in Front using React

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.

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 proxy not working

My app uses a Python backend so when I'm running locally I need to proxy my requests to a different port than what Webpack is running on.
I've tried several different ways of making this work:
devServer: {
contentBase: outDir,
proxy: [
{
path: "**",
target: "http://localhost:8000",
secure: false,
bypass: function(req, res, options) {
if(req.url === '' || req.url === '/') {
res.statusCode = 302;
res.setHeader('Location', '/a/');
return '/a/';
}
var frontend = new RegExp("^\/$^|\/a\/index\.html|^\/a\/|^\/a$|^\/styleguide");
if (frontend.test(req.url)) return req.url;
}
}
],
// serve index.html for all 404 (required for push-state)
historyApiFallback: true,
},
And this:
proxy: [{
context: '/',
target: 'http://localhost:8000',
}],
Both of those will at least show a message similar to this when it starts up: [HPM] Proxy created: ** -> http://localhost:8000. When I look at the docs and do something like this, it doesn't work either (I don't even get a message about the proxy running):
proxy: {
"/": "http://localhost:8000"
}
Is there something obvious I'm doing wrong? I'be been trying every combination that I can think of to make it work.
Try to add changeOrigin: true. Don't forget to change API pattern.
proxy: {
'/api/**': {
target: 'http://localhost:8000',
secure: false,
changeOrigin: true
},
}

Webpack / React/ Spring Boot: caching bundle.js with https

In my Spring-Boot/React application, i want to cache bundle.js(1.2Mb). If i run the app with http://(test-envionment-server-url)/myapp, my bundle.js get called from cache (208 B) with HTTP status 304 every time i refresh the page. Until now everything is fine.
But when i use https://(test-envionment-server-url)/myapp, bundle.js is not cached and each time i refresh it gets all 1.2Mb, yet all other images and font get cached.
I am using Tomcat in local, and JBoss 7.0.x in my test environment.
Here is my webpack.config.js
const webpack = require('webpack');
const autoprefixer = require('autoprefixer');
module.exports = {
cache: true,
entry: [
'webpack-dev-server/client?http://localhost:8008',
'webpack/hot/only-dev-server',
'babel-polyfill',
'./src/index.js',
],
module: {
loaders: [
{
test: /\.jsx?$/,
exclude: /node_modules/,
loader: 'react-hot!babel',
},
{
test: /\.(jpe?g|png|gif|svg)$/i,
loaders: [
'url?limit=2048',
'img',
],
},
{
test: /\.(woff|woff2|eot|ttf)$/,
loader: 'url-loader?limit=2048',
},
{
test: /\.scss$/,
loaders: ['style', 'css', 'postcss-loader', 'sass'],
},
],
},
resolve: {
extensions: ['', '.js', '.jsx'],
},
output: {
path:`${__dirname}/(spring-boot-app-url/resources/static`,
publicPath: '/publicpath/',
filename: 'bundle.js',
},
devServer: {
port: 8008,
contentBase: './dist',
historyApiFallback: true,
hot: true,
proxy: {
.....(proxy config)
},
},
},
},
postcss: () => {
return [autoprefixer];
},
plugins: [
new webpack.HotModuleReplacementPlugin(),
new webpack.optimize.UglifyJsPlugin(),
new webpack.optimize.DedupePlugin(),
new webpack.DefinePlugin({
'process.env': {
'NODE_ENV': JSON.stringify('production'),
},
}),
],
};
in my Spring i have some Spring security configuration:
#Override
protected void configure(HttpSecurity httpSecurity) throws Exception {
httpSecurity
.csrf().disable()
.authorizeRequests()
.antMatchers(TOKEN_NAME).permitAll() // API
...(antMatchers)
.and()
.authorizeRequests()
.antMatchers(TOKEN_BASED_AUTH_ENTRY_POINT).permitAll();
httpSecurity
.addFilterBefore(authenticationTokenFilterBean(), UsernamePasswordAuthenticationFilter.class);
httpSecurity.headers().cacheControl().disable();
}
Here is the Request header from my Network tab:
Accept:*/*
Accept-Encoding:gzip, deflate, sdch, br
Accept-Language:fr-FR,fr;q=0.8,en-US;q=0.6,en;q=0.4
Connection:keep-alive
Host:*****
Referer:https://****/appname/
User-Agent:Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.99 Safari/537.36
Here is the Response header from Network tab:
Accept-Ranges:bytes
Cache-Control:max-age=3600
Connection:keep-alive
Content-Length:1248915
Content-Type:application/javascript; charset=UTF-8
Date:Mon, 05 Dec 2016 12:56:47 GMT
Last-Modified:Mon, 05 Dec 2016 09:08:06 GMT
Server:JBoss-EAP/7
Strict-Transport-Security:max-age=31536000 ; includeSubDomains
X-Content-Type-Options:nosniff
X-Frame-Options:DENY
X-Powered-By:Undertow/1
X-XSS-Protection:1; mode=block
When i run it with http url, the header request doesn't have any cache control.
Any idea about how to cache bundle.js file even when i run my app using https?
Thank you
Given the provided HTTP response, it seems your server is not sending the appropriate Cache-Control headers. Doing so can cause issues when you're changing the contents of your static resource.
This is why you should:
configure a Cache-Control header to be sent when serving static resources
configure a resource chain with a content strategy (see here)
The overall configuration for your production profile should look like:
spring.resources.cache-period=3600 # caching resources for 1 hour
spring.resources.chain.strategy.content.enabled=true
spring.resources.chain.strategy.content.paths=/**
the problem was in my JBoss Configuration:
in standalone.xml i added gzip compression properties :
<system-properties>
<property name="org.apache.coyote.http11.Http11Protocol.COMPRESSION" value="on"/>
<property name="org.apache.coyote.http11.Http11Protocol.COMPRESSION_MIME_TYPES" value="text/javascript,text/css,text/html,application/xml,application/json"/>
<property name="org.apache.coyote.http11.Http11Protocol.COMPRESSION_MIN_SIZE" value="1024"/>
</system-properties>
right under extensions.

Resources