SaveLolliPoP
@SaveLolliPoP
1 / 0 = ∞

Почему angular не редеректит, а пытается загрузить html?

Бекенд nodejs - express, passport.
Фронтенд ангуляр.

//Настроенные роуты для angular
app.use('/', express.static(path.join(__dirname, '/dist/practice/')));
app.get('*', function(req, res) {
    res.sendFile(path.join(__dirname, '/dist/practice/index.html'));
});
app.use('/', router);


//Обработчик post запроса на сервере (Как во всех гуидах)
router.post('/login', (req, res, next) => {
    passport.authenticate('local', {
        successRedirect : '/profile',
        failureRedirect : '/error',
        failureFlash : true
    })(req, res, next);
});


//Сервис который обрабатывает запросы с клиента (angular)
headers: new HttpHeaders({
    'Content-Type':  'application/json',
    'Authorization': 'my-auth-token'
  })

postData(user) {
      return this.http.post('/login', user, httpOptions);
  }


//Функция вызванная в компоненте
  onSubmit(){
      this.httpService.postData(JSON.stringify(this.user))
        .subscribe(data=>{
          console.log(data);
          this.done=true;
        },
        error => console.log(error)
      );
  }


//Сама форма
<section class="login">
  <div class="wrapper">
    <form class="example-form" (ngSubmit)="onSubmit()" #userform="ngForm">
      <h1>Зарегистрируйтесь сейчас</h1>
      <mat-form-field class="example-full-width">
        <input matInput [(ngModel)]="user.email" name="email" type="email" placeholder="Email">
        <mat-error *ngIf="">
          Email is <strong>required</strong>
        </mat-error>
      </mat-form-field>

      <mat-form-field class="example-full-width">
        <input matInput [(ngModel)]="user.password" name="password" type="password" placeholder="Password" >
      </mat-form-field>
      <div *ngIf="done">
          <div>Получено от сервера:</div>
          <div>Имя: {{receivedUser.email}}</div>
          <div>Возраст: {{receivedUser.password}}</div>
      </div>
      <button mat-raised-button type="submit" color="primary">Регистрация</button>
    </form>
    <p class="lead">Уже зарегистрированы? <a href="#" (click)="openBottomSheet()">Войти</a></p>

  </div>
</section>


На сервер поступают post запросы, обрабатываются, но возвращается ошибка, и редиректа по понятным причинам не происходит.
Ошибка происходит на клиенте в файле main.adeca9df8fe2d81d2855.js.

e {headers: t, status: 200, statusText: "OK", url: "http://localhost:3000/profile", ok: false, …}


Если раскрыть ошибку, то:
error: {error: SyntaxError: Unexpected token < in JSON at position 0 at JSON.parse (<anonymous>) at XMLHttp…, text: "<!doctype html>↵<html lang="en">↵<head>↵


Так же само сообщение:
message: "Http failure during parsing for http://localhost:3000/profile"


Зачем он его парсит? Что сделать чтобы он не парсил файл, а переходи по ссылке?

PS: По */profile роутеры на ангуляр настроены.
  • Вопрос задан
  • 189 просмотров
Решения вопроса 1
search
@search
мама говорит что я особенный
1. Angular не будет редиректить. Он так не работает. Он использует XmlHttpRequest под капотом, а XHR работает так в вашем случае: выполняет запрос -> получает редирект от сервера -> идёт по адресу редиректа -> достаёт по этому адресу полученный ответ и возвращает ангуляру. А ангуляр пытается распарсить полученный ответ. И ожидает при этом получить JSON, но получает при этом HTML, поэтому выдаёт ошибку

2. this.httpService.postData(JSON.stringify(this.user)). Тут не совсем понятно зачем юзер превращается в строку и затем строка постится. Обычно постится сразу JSON объект. Если только там не какая-то дикая дичь на сервере. Но лучше решить вопрос путём поста JSON объекта, а не строки. Меньше страдать прийдётся

Теперь по подводу редиректов на стороне сервера. SPA так не работают. Сервак не занимается редиректами. Это не его работа. Работа сервака вернуть JSON ответ и HTTP status 200 в случае если он может вернуть то что от него ждут. И ошибку в противном случае. Вот тут подробнее https://en.wikipedia.org/wiki/List_of_HTTP_status_codes

Вобще, если хотите, не сильно расстраиваться из-за дурацкого Ангуляра (да и любого другого SPA фреймворка), то желательно ознакомиться и начать использовать oAuth или JWT.

Если вы дочитали до этого момента и сказали "ну тебя в баню со своими советами, я хочу чтоб редиректило как у нормальных пацанов", то можете сделать это вот так:

import { tap } from 'rxjs/operators';

return this.http.post('/login', user, {observe: 'response', responseType: 'text'}).pipe(
  tap(response => {
    location.href = response.url;
  })
);
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

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

Похожие вопросы