简体   繁体   中英

Angular10 - XHR failed loading: POST - Browser blocks HTTP Request to domain of identical name

I have a webpage consisting of a Django REST API and an Angular 10 Frontend SPA. Generally I can send GET-, POST-, PUT- and DELETE-XHR Requests to my backend without issue, I only have a single API Endpoint where categorically my SPA's requests are cancelled, somehow. The issue occurs on both Chrome and Firefox and seems browser independant. The error message I receive in google chrome is:

zone-evergreen.js:2845 XHR failed loading: POST "https://www.aldrune.com/wiki1/api/timestamp/".

This is the information we have about that:

  1. The HTTP Request is being cancelled after it is constructed by either the browser or the SPA (Below information from the chrome network tab) 在此处输入图像描述 在此处输入图像描述

  2. Restarting the HTTP Request in the Network Tab in chrome gives back a correct response from the backend, proving that the HTTP Request object was constructed correctly在此处输入图像描述

  3. The backend is working correctly (Based on 2. and that I can send HTTP Requests via postman successfully)

  4. It can't be CORS related, as both SPA and my Backend are served from the same HTTP Server (Apache2) . Even if that weren't enough, Django is currently configured to allow all origins.

Other questions with this issue had unintentional page-reloads as their cause, which interrupted the AJAX Request. But nothing in my component should trigger a page reload when the request is created via createTimestamp() . The component literally takes the 2 input DOM elements required from the HTML and builds the object that is to be sent itself. No form submission involved.

//session-audio.component.html
...
            <!-- Timestamp Create Form -->
            <div [ngClass]="{'d-none': !timestampCreateState, 'row my-1': timestampCreateState}">
                <input type="text" name="time" #timestampTimeInput />
                <input type="text" name="title" #timestampNameInput />
                <div>
                    <i class="icon hover-red fa fa-1-5x fa-times mx-1" (click)="cancelTimestampCreateState()"></i>
                    <i class="icon hover-green fa fa-1-5x fa-check mx-1" (click)="createTimestamp(timestampTimeInput, timestampNameInput)"></i>
                </div>
            </div>
...
//session-audio.component.ts
export class SessionAudioComponent implements OnInit {
...
  createTimestamp(timestampTimeInput: any, timestampNameInput: any){
    this.timestamp_model.time = this.stringToTime(timestampTimeInput.value);
    this.timestamp_model.name = timestampNameInput.value;
    //session_audio is set during initialization of this.timestamp_model

    this.timestampService.createTimestamp(this.timestamp_model).subscribe(timestamp => {
      this.timestamps.unshift(timestamp);
      this.timestampCreateState = false;
    }, error => console.log(error)).unsubscribe();
  }

}

My best guess is that it's something with the component, but what?

The error is indeed caused by the request being interrupted, in this case by the observable being unsubscribed from before it can even finish making the request to the backend. The issue happens in the createTimestamp() function of my componen. I left out the callback-functions in subscribe to emphasize my point::

 this.timestampService.createTimestamp(this.timestamp_model).subscribe(...).unsubscribe();

The lesson:

Do not unsubscribe from an observable immediately after subscribing to it . That will interrupt your call.

If you want a single use Observable that is unsubscribed from after you get the first value, use the default method that is recommended everywhere: use the rxjs pipe method with the first() operator.

  createTimestamp(timestampTimeInput: any, timestampNameInput: any){
    this.timestamp_model.time = this.stringToTime(timestampTimeInput.value);
    this.timestamp_model.name = timestampNameInput.value;
    //session_audio is set during initialization of this.timestamp_model

    this.timestampService.createTimestamp(this.timestamp_model).pipe(first()).subscribe(timestamp => {
      this.timestamps.unshift(timestamp);
      this.timestampCreateState = false;
    }, error => console.log(error));
  }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM