Установите порт сервера для отправки запросов API от Angular к NodeJS в разработке

У меня есть это приложение MEAN Stack, а для внешнего интерфейса я использую Angular 6, я создал систему рутирования пользователей и внутреннюю систему входа в систему, я протестировал ее с помощью Postman, и она работает, как ожидалось. но когда я использую форму, я всегда получаю эту ошибку ниже:

Установите порт сервера для отправки запросов API от Angular к NodeJS в разработке

Я знаю, что проблема в том, чтобы изменить порт с 4200 на 3000, но не нашел правильного решения.

вот моя услуга:

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { map } from 'rxjs/operators';

@Injectable()
export class UserService {

  constructor(
    private _httpClient: HttpClient
  ) { }


  public auth(user) {
    return this._httpClient.post('users/login', user).pipe(map((resp: any) => resp.json()));
  }

}

и вот где я пользуюсь сервисом:

import { Component, OnInit } from '@angular/core';
import { Router } from '@angular/router';
import { UserService } from '../../services/user.service';



@Component({
  selector: 'app-side-menu',
  templateUrl: './side-menu.component.html',
  styleUrls: ['./side-menu.component.scss']
})
export class SideMenuComponent implements OnInit {

  public positionsList: Array<any> = [];
  public selectedOption: string;
  public feedbackMessage: string;

  public email: string;
  public password: string;

  public formNotValid: boolean;

  constructor(
    private _userService: UserService,
    private _router: Router
  ) { 

  }

  ngOnInit() {
  }

  public sendLoginForm() {
    if (!this.email || !this.password){
      this.formNotValid = true;
      this.feedbackMessage = "Both fields are required to login!";
      return false;
    }

    const user = {
      email: this.email,
      password: this.password
    }

    this._userService.auth(user).subscribe(resp => {
      if (!resp.success){
        this.feedbackMessage = resp.message;
        return false;
      }
    });
  }

  public getSelectedOption(option) {
    this.selectedOption = "as " + option;
  }


}

Любая идея будет оценена по достоинству.

На каком порту вы запускаете свое угловое приложение? Что там говорится о порте после ввода ng serve?

Apar Adhikari 26.10.2018 10:28

Для Node я использую порт 3000 и 4200 для приложения Angular, я знаю, что это должен быть порт, потому что в почтальоне я использовал это: localhost:3000/users/login, и он работает, для Angular я использую этот this._httpClient.post('users/login', user). Но на консоли он показывает: POST http://localhost:4200/users/login 404 (Not Found)

Najm Eddine ZAGA 26.10.2018 10:32

Ага, настройте ng serve с прокси - см. Мой ответ.

PeS 26.10.2018 10:34

Это связано с тем, что вы не указали хост и порт в своей службе, поэтому приложение angular считает текущий запущенный хост вашим хостом по умолчанию, то есть localhost: 4200. Используйте это: верните this._httpClient.post ('локальный: 3000 / пользователей / логин', user) .pipe (map ((соответственно: any) => resp.json ()));

Apar Adhikari 26.10.2018 10:40

он дал мне: Failed to load localhost:3000/users/login: Cross origin requests are only supported for protocol schemes: http, data, chrome, chrome-extension, https.

Najm Eddine ZAGA 26.10.2018 10:45

Проверьте мой ответ ниже. Это тоже решит.

Apar Adhikari 26.10.2018 10:52

возможно, есть проблема с пользовательским интерфейсом. можете ли вы поделиться своим html-кодом

bhaumik shah 26.10.2018 10:54
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
5
7
5 576
4
Перейти к ответу Данный вопрос помечен как решенный

Ответы 4

Вы должны настроить прокси в Angular ng serve для перенаправления запросов к вашему API. Измените package.json для запуска ng serve с параметрами:

"scripts": {
   .....
   "start": "ng serve --proxy-config proxy.config.json",
   .....
}

и создайте proxy.config.json для пересылки запросов к вашему бэкэнду, например, предполагая, что ваш бэкэнд работает на той же машине и на порту 3000:

{
  "/api/*": {
   "target": "http://localhost:3000",
   "secure": false
  },
  "/__/*": {
    "target": "http://localhost:3100",
    "secure": false
  }
}

Я считаю, что это также можно настроить в angular.json, но никогда не исследовал этот вариант.

Обновлено: вот как это настроить в angular.json (документы):

Откройте angular.json и найдите ключ "serve"; затем в "options" ниже укажите путь к файлу конфигурации прокси в ключе "proxyConfig":

"serve": {
  "builder": "@angular-devkit/build-angular:dev-server",
  "configurations": {
     "production": {
        ...
     },
     "development": {
        ...
     }
  },
  "defaultConfiguration": "development",
  "options": {
     "proxyConfig": "proxy.config.json"
  }
}
Ответ принят как подходящий

Вы можете просто использовать полный URL-адрес в своем вызове следующим образом

this._httpClient.post(window.location.protocol + '//' + window.location.hostname + ':3000/' + 'users/login', user)

В идеале у вас должны быть микросервисы за обратным прокси-сервером и маршрутизация запросов на основе путей URI.

Это не будет работать в производственной среде, если сервер также не будет работать на порте 3000 в производственной среде.

PeS 26.10.2018 10:33

Даже в режиме разработки Failed to load http://localhost:3000/users/login: 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:4200' is therefore not allowed access.

Najm Eddine ZAGA 26.10.2018 10:38

@PeS Ага. Я предложил это как обходной путь во время разработки, но в идеале в таких случаях следует позаботиться о обратном прокси-сервере в производственной среде. Ваш ответ лучше, кстати, для развития. :)

Pramodh Valavala 26.10.2018 10:45

@NajmEddineZAGA Вам нужно будет включить CORS на вашем сервере, работающем на порте 3000. Если это экспресс-сервер, установите модуль cors с npm install cors, а затем добавьте его в качестве промежуточного программного обеспечения, например app.use(cors()). Обратитесь к это для получения дополнительной информации.

Pramodh Valavala 26.10.2018 10:47

Ошибки больше нет, думаю можно сработать. Мне нужно исправить еще одну проблему с ответом, и если это так, я дам вам знать

Najm Eddine ZAGA 26.10.2018 10:55

@PramodhValavala Я предложил это как обходной путь во время разработки, но в идеале в таких случаях следует позаботиться о обратном прокси-сервере в производственной среде. ... ну да. Тогда вам придется иметь дело с CORS, настройка прокси в производстве менее безопасна (вы должны в основном открывать узел напрямую в Интернет) или более сложная ... Настройка прокси в разработке делает этот прозрачный и одинаковый опыт как для разработчиков, так и для производства. Но как бы то ни было, не хочу спорить :) OP должен решать, с чем он хочет иметь дело ....

PeS 26.10.2018 11:08

Вы можете попробовать поместить URL-адрес для вызовов api в переменную, а затем добавить его в URL-адрес http-глаголов с конкретным маршрутом.

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { map } from 'rxjs/operators';

@Injectable()
export class UserService {
url='http://localhost:3000/'
  constructor(
    private _httpClient: HttpClient
  ) { }


  public auth(user) {
    return this._httpClient.post(this.url+'users/login', user).pipe(map((resp: any) => resp.json()));
  }

}
Failed to load http://localhost:3000/users/login: 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:4200' is therefore not allowed access.
Najm Eddine ZAGA 26.10.2018 10:49

добавьте плагин cors в свой файл узла. cors разрешает ответ на запрос от другого источника.

Anurag 26.10.2018 10:57

в приложении вашего узла вы должны разрешить запрос от __http: // localhost: 4200 origin. решение, предоставленное @Apar Adhikari, должно быть в порядке.

R.Sarkar 26.10.2018 10:57

Если вы работаете с разными средами, вы можете настроить их в файлах среды.

Например, ваш evironment.dev.ts будет выглядеть так

export const environment = {
  production: false,
  API_REST_URL: 'https://yourDomainName', // can be http://localhost as well
  API_REST_PORT: 3000
};

И в вашем сервисе вы бы использовали это так

import { environment } from '/path/to/environment';

@Injectable()
export class MyService{
  apiPort = environment['API_REST_PORT'];
  apiUrl = environment['API_REST_URL'];

  constructor(private http: HttpClient) {
  }

  apiCall(): Observable<any> {
    return this.http.get(`${this.apiUrl}:${this.apiPort}/endpoint/path`)
      .pipe(map(data => {
        return data;
      }));
  }
}

А для обслуживания вашего приложения в среде dev вы можете добавить свою команду в scripts object в package.json.

 "scripts": {
    ...
    "start-dev": "ng serve --configuration=dev",
    "build:dev": "ng build --configuration=dev",
    ...
  },

Другие вопросы по теме