A
A
Andrey Ivanov2020-10-02 20:45:12
Nginx
Andrey Ivanov, 2020-10-02 20:45:12

Why is the network request to the server from the client (react) not going through?

There is a configuration for Nginx

server {
        listen 80;

        server_name alexandra-portfolio.proto-dev.ru www.alexandra-portfolio.proto-dev.ru;

        location / {
            root /var/www/develop/frontend/alexandra-portfolio;
            try_files $uri /index.html;
        }

        location /admin {
            alias /var/www/develop/frontend/alexandra-portfolio-admin/build;
            index  index.html index.htm;
            try_files $uri /admin/index.html;
        }

        location /build {
            root /var/www/develop/frontend/alexandra-portfolio-admin/build;
            autoindex off;
        }

        location /swagger {
            proxy_pass http://localhost:4000;
        	proxy_http_version 1.1;
        	proxy_set_header Upgrade $http_upgrade;
        	proxy_set_header Connection 'upgrade';
        	proxy_set_header Host $host;
        	proxy_cache_bypass $http_upgrade;
        }

        location /api {
        	proxy_pass http://localhost:4000;
        	proxy_http_version 1.1;
        	proxy_set_header Upgrade $http_upgrade;
        	proxy_set_header Connection 'upgrade';
        	proxy_set_header Host $host;
        	proxy_cache_bypass $http_upgrade;
  }
}


There is a webpack 4 configuration

const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
const TerserPlugin = require('terser-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const { DefinePlugin } = require('webpack');
const dotEnv = require('dotenv').config();

const isEnvProduction = process.env.NODE_ENV === 'production';

module.exports = {
  mode: process.env.NODE_ENV,
  entry: {
    main: [ 'whatwg-fetch', '@babel/polyfill', './src/index.js' ],
  },
  output: {
    path: path.resolve(__dirname, 'build'),
    filename: isEnvProduction ? '[name].[hash:10].js' : '[name].js',
    chunkFilename: isEnvProduction ? '[name].[hash:10].chunk.js' : '[name].chunk.js',
    publicPath: './',
  },
  resolve: {
    modules: [ path.resolve(__dirname, 'node_modules') ],
    ...require('./webpack.config.alias').resolve,
  },
  module: {
    rules: [
      {
        test: /\.(js|jsx)$/,
        exclude: [
          /node_modules\/(?!ansi-regex).*/,
        ],
        use: {
          loader: 'babel-loader',
          options: {
            presets: [
              [ '@babel/preset-env', { modules: false } ],
              '@babel/preset-react',
            ],
            plugins: [
              [
                'babel-plugin-styled-components',
                {
                  ssr: false,
                  displayName: !isEnvProduction,
                  fileName: false,
                  minify: isEnvProduction,
                  transpileTemplateLiterals: isEnvProduction,
                  pure: false,
                },
              ],
              '@babel/plugin-transform-regenerator',
              '@babel/plugin-proposal-class-properties',
            ],
          },
        },
      },
      {
        test: /\.font\.js/,
        use: [
          MiniCssExtractPlugin.loader,
          'css-loader',
          {
            loader: 'webfonts-loader',
            options: {
              fileName: '[name].[hash:8].[ext]',
            },
          },
        ],
      },
      {
        test: /\.(jpg|jpeg|png|gif|svg)$/,
        loader: 'file-loader',
        options: {
          name: '[name].[hash:8].[ext]',
        },
      },
      {
        test: /\.(ttf|eot|woff2?)$/,
        loader: 'file-loader',
        options: {
          name: '[name].[ext]',
        },
      },
      {
        test: /\.css$/i,
        use: [ 'style-loader', 'css-loader' ],
      },
    ],
  },
  devServer: {
    open: true,
    overlay: true,
    port: process.env.PORT,
    quiet: true,
    disableHostCheck: true,
    writeToDisk: true,
    historyApiFallback: true,
    proxy: {
      '/api': {
        target: process.env.PROXY_URL,
      },
      '/uploads': {
        target: process.env.PROXY_URL,
      },
    },
  },
  optimization: {
    minimize: isEnvProduction,
    minimizer: [
      new TerserPlugin({
        terserOptions: {
          parse: {
            ecma: 8,
          },
          warnings: false,
          compress: {
            ecma: 5,
            warnings: false,
            comparisons: false,
            inline: 2,
          },
          mangle: true,
          output: {
            ecma: 5,
            comments: false,
            ascii_only: true,
          },
        },
        parallel: true,
        cache: true,
        sourceMap: true,
      }),
    ],
    splitChunks: {
      chunks: 'all',
    },
  },
  devtool: isEnvProduction ? 'source-map' : 'eval-cheap-module-source-map',
  performance: false,
  plugins: [
    new DefinePlugin({
      'process.env': JSON.stringify(dotEnv.parsed),
    }),
    new HtmlWebpackPlugin({
      template: './src/index.html',
      filename: './index.html',
      favicon: './src/assets/images/favicon.ico',
      showErrors: true,
      inject: true,
    }),
    new CleanWebpackPlugin(),
    new MiniCssExtractPlugin({
      filename: '[name].[hash:10].css',
    }),
  ],
};


File structure for React frontend on remote server
5f77632a9bb9a932115911.png
File structure for Nest backend on remote server
5f7763705840c584319042.png

Service that makes requests to the backend
The process.env.PROXY_URL variable on the prod becomes PROXY_URL= proto-dev.ru:4000 because Nest is running on port 4000

import { store } from 'Store/index';
import { API_BASE } from 'Constants/httpRequest';

import * as userActions from 'Store/user/actions';
import * as appActions from 'Store/app/actions';

import getErrorNameFromResponse from 'Helpers/getErrorNameFromResponse';

import { SERVICE_MODAL_TYPES } from 'Constants/modalTypes';

const isEnvProduction = process.env.NODE_ENV === 'production';

const REQUEST_DEFAULT_OPTIONS = {
  method: 'GET',
  contentType: 'application/json',
  body: false,
  query: {},
};

const parseResponse = (response) => {
  const contentType = response.headers.get('Content-Type') || '';

  if (contentType.includes('json')) {return response.json();}
  if (contentType.includes('text')) {return response.text();}

  return response.blob();
};

const handleResponse = async (response) => {
  if (response.ok) {
    return await parseResponse(response);
  }

  if (response.status === 401) {
    store.dispatch(userActions.signOut());
  }

  if (response.status >= 400 && response.status <= 500) {
    const parsedResponse = await parseResponse(response);

    return {
      errorText: getErrorNameFromResponse(parsedResponse.error.message),
    };
  }
};

const handleRequestFail = (error) => {
  console.error(error);

  store.dispatch(appActions.showServiceModalAction({
    type: SERVICE_MODAL_TYPES.infoModal,
    contentProps: {
      title: 'Что-то пошло не так...',
      cancelButtonText: 'Закрыть',
      onCancel: () => store.dispatch(appActions.hideServiceModalAction()),
    },
  }));
};

export default (route, options = {}) => {
  const accessToken = localStorage.getItem('accessToken') || '';

  const {
    contentType,
    method,
    body,
    query,
  } = { ...REQUEST_DEFAULT_OPTIONS, ...options };

  const fetchConfig = {
    headers: {
      'Authorization': `Bearer ${accessToken.replace(/"/g, '')}`,
    },
    method,
  };

  if (body && method !== 'GET') {
    fetchConfig.body = body;
  }

  if (contentType) {
    fetchConfig.headers['Content-Type'] = contentType;
  }

  const urlObject = new URL(`${API_BASE}${route}`, process.env.PROXY_URL);

  for (const key in query) {
    urlObject.searchParams.append(key, query[key]);
  }

  return fetch(urlObject, fetchConfig)
    .then(handleResponse)
    .catch(handleRequestFail);
};


The problem is that I make a request from the browser to Nest and get an error. How to bypass it, what is this error?
5f77671b4f862802577744.png
5f7766e50b157883240166.png

Answer the question

In order to leave comments, you need to log in

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question