Angular10 - XHR 加载失败:POST - 浏览器阻止对同名域的 HTTP 请求
Angular10 - XHR failed loading: POST - Browser blocks HTTP Request to domain of identical name
我有一个由 Django REST API 和 Angular 10 前端 SPA 组成的网页。通常,我可以毫无问题地将 GET-、POST-、PUT- 和 DELETE-XHR 请求发送到我的后端,我只有一个 API 端点,我的 SPA 请求肯定被取消了,不知何故。 Chrome 和 Firefox 都会出现此问题,并且似乎与浏览器无关。我在 google chrome 中收到的错误消息是:
zone-evergreen.js:2845 XHR failed loading: POST "https://www.aldrune.com/wiki1/api/timestamp/".
这是我们掌握的相关信息:
HTTP 请求在由浏览器或 SPA 构造后被取消(chrome 网络选项卡中的信息下方)
在chrome的网络选项卡中重新启动HTTP请求从后端返回正确的响应,证明HTTP请求对象构造正确
后端正常工作(基于2.并且我可以通过邮递员成功发送HTTP请求)
它不能与 CORS 相关,因为 SPA 和我的后端都是从同一个 HTTP 服务器 (Apache2) 提供的。即使这还不够,Django 当前配置为允许所有来源。
有关此问题的其他问题的原因是无意的页面重新加载,这中断了 AJAX 请求。但是当通过 createTimestamp()
创建请求时,我的组件中的任何内容都不应触发页面重新加载。该组件从字面上获取 HTML 所需的 2 个输入 DOM 元素,并构建要发送的对象本身。不涉及表单提交。
//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();
}
}
我最好的猜测是它与组件有关,但是什么?
错误确实是由于请求被中断引起的,在本例中是由于 observable 在它甚至可以完成向后端发出请求之前被取消订阅。问题发生在我组件的 createTimestamp()
函数中。我省略了订阅中的回调函数以强调我的观点::
this.timestampService.createTimestamp(this.timestamp_model).subscribe(...).unsubscribe();
教训:
不要在订阅后立即取消订阅 observable。 会打断你的通话。
如果你想要在获取第一个值后取消订阅的单次使用 Observable,请使用到处推荐的默认方法:使用 rxjs pipe
方法和 first()
运算符。
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));
}
我有一个由 Django REST API 和 Angular 10 前端 SPA 组成的网页。通常,我可以毫无问题地将 GET-、POST-、PUT- 和 DELETE-XHR 请求发送到我的后端,我只有一个 API 端点,我的 SPA 请求肯定被取消了,不知何故。 Chrome 和 Firefox 都会出现此问题,并且似乎与浏览器无关。我在 google chrome 中收到的错误消息是:
zone-evergreen.js:2845 XHR failed loading: POST "https://www.aldrune.com/wiki1/api/timestamp/".
这是我们掌握的相关信息:
HTTP 请求在由浏览器或 SPA 构造后被取消(chrome 网络选项卡中的信息下方)
在chrome的网络选项卡中重新启动HTTP请求从后端返回正确的响应,证明HTTP请求对象构造正确
后端正常工作(基于2.并且我可以通过邮递员成功发送HTTP请求)
它不能与 CORS 相关,因为 SPA 和我的后端都是从同一个 HTTP 服务器 (Apache2) 提供的。即使这还不够,Django 当前配置为允许所有来源。
有关此问题的其他问题的原因是无意的页面重新加载,这中断了 AJAX 请求。但是当通过 createTimestamp()
创建请求时,我的组件中的任何内容都不应触发页面重新加载。该组件从字面上获取 HTML 所需的 2 个输入 DOM 元素,并构建要发送的对象本身。不涉及表单提交。
//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();
}
}
我最好的猜测是它与组件有关,但是什么?
错误确实是由于请求被中断引起的,在本例中是由于 observable 在它甚至可以完成向后端发出请求之前被取消订阅。问题发生在我组件的 createTimestamp()
函数中。我省略了订阅中的回调函数以强调我的观点::
this.timestampService.createTimestamp(this.timestamp_model).subscribe(...).unsubscribe();
教训:
不要在订阅后立即取消订阅 observable。 会打断你的通话。
如果你想要在获取第一个值后取消订阅的单次使用 Observable,请使用到处推荐的默认方法:使用 rxjs pipe
方法和 first()
运算符。
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));
}