0

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?

halfer
  • 19,824
  • 17
  • 99
  • 186
mitsu
  • 429
  • 2
  • 10
  • 23
  • possible duplicate of : https://stackoverflow.com/questions/20035101/why-does-my-javascript-code-get-a-no-access-control-allow-origin-header-is-pr - Essentially you are performing a cross domain request, so you'll have to either proxy or change the remote server if its under your control. – Squiggs. Dec 17 '19 at 17:30
  • hello Squiggs, thank you for your answer. How can i do hundle that with the proxy please ? because am admin of the server but i don't knwo how to change remote as you say – mitsu Dec 17 '19 at 17:48
  • For each resource/page that Site B wants to make accessible to Site A, Site B should serve its pages with the response header: Access-Control-Allow-Origin: http://siteA.com So, in your case, you will need a header that allows your localhost when in development. – Squiggs. Dec 17 '19 at 20:56
  • what you mean by siteA and siteB ?i have only one site : fatboar.extia.com :/ – mitsu Dec 17 '19 at 20:57
  • Nope. you have two sites. The Machine you are making the request from (http://localhost:3000), and the API you are contacting.(fatboar.extia.com) – Squiggs. Dec 17 '19 at 21:03
  • in my case, i need to add this : 'Access-Control-Allow-Origin': 'fatboar.extia.com' to my header right ? – mitsu Dec 17 '19 at 22:44
  • origin 'http://localhost:3000' has been blocked by CORS policy not 'fatboar.extia.com' therefore Access-Control-Allow-Origin: http://localhost:3000 – Squiggs. Dec 18 '19 at 08:55
  • hey, according to my post, where can i put this code ( header: Access-Control-Allow-Origin: siteA.com) please ? is it in fetch ? – mitsu Dec 18 '19 at 18:32
  • 1
    you don't put that code anywhere in the client side or within your code. It has to exist on the server side within the API you are talking to. You mention you are the 'admin of the server' - which I have assumed means you have access to the source of the API. In other words: https://api.exhia.com/api/accounts/addaccount needs to change – Squiggs. Dec 19 '19 at 08:20

2 Answers2

1

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.

Squiggs.
  • 4,299
  • 6
  • 49
  • 89
0

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.

  • hello Squiggs, thank you for your answer. it's on prod not dev , please take a lookto the webpack.config in Edit above – mitsu Dec 17 '19 at 17:43
  • you say that i need to to disable the cors check in browser, but every would not do that :/ – mitsu Dec 17 '19 at 17:46
  • Disabling cors and proxy are something which usually we do in development environment. In production environment the API server should allowed host configuration or all apps should be hosted in the same domain, I would suggest please see cors documentation here is a good explanation https://stackoverflow.com/questions/36958999/cors-is-it-a-client-side-thing-a-server-side-thing-or-a-transport-level-thin – Nirjhar K. Paul Dec 17 '19 at 17:54
  • hey Nirjhar, it didn't really help me to resolve my issue unfortunately it just explains the concept of cross .. – mitsu Dec 17 '19 at 18:48