newdecline
@newdecline
Front-end-developer

Почему сетевой запрос на сервер с клиента (react) не проходит?

Имеется конфигурация для 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;
	}
}


Имеется конфигурация webpack 4

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


Файловая структура для фронтенда-React на удаленном сервере
5f77632a9bb9a932115911.png
Файловая структура для бекенда-Nest на удаленном сервере
5f7763705840c584319042.png

Сервис который делает запросы к бэкенду
Переменная на проде process.env.PROXY_URL приобретает значение PROXY_URL=proto-dev.ru:4000 потому что Nest запущен на 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);
};


Проблема в том что я делаю запрос с браузера на Nest и получаю ошибку. Как ее обойти, что это за ошибка ?
5f77671b4f862802577744.png
5f7766e50b157883240166.png
  • Вопрос задан
  • 76 просмотров
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы