spring - 服务器发送事件错误 : 406 (Not Acceptable) in Angular5 + Spring App

标签 spring angular5 observable server-sent-events eventsource

我正在使用 Angular5 应用程序,我需要在仪表板上显示实时数据。我们的后端是用 spring(v4.x) 编写的,它具有在生成任何服务器事件时发送结果的 api。

但是当我在 Angular 应用程序中调用这个 api 时,它总是给我

GET http://192.168.1.9:8080/proxta/api/student-answered-correctly-by-que_nft 406 (Not Acceptable)

响应 header (从网络复制)

Access-Control-Allow-Credentials: true
Access-Control-Allow-Origin: http://192.168.1.9:4200
Access-Control-Expose-Headers: Authorization, Link, X-Total-Count
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Connection: keep-alive
Content-Length: 0
Content-Type: text/event-stream;charset=UTF-8
Date: Mon, 22 Oct 2018 09:50:59 GMT
Expires: 0
Pragma: no-cache
Vary: Access-Control-Request-Headers
Vary: Access-Control-Request-Method
Vary: Origin
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block

请求 header

GET /proxta/api/student-answered-correctly-by-que_nft HTTP/1.1
Host: 192.168.1.9:8080
Connection: keep-alive
Accept: text/event-stream
Cache-Control: no-cache
Origin: http://192.168.1.9:4200
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36
Referer: http://192.168.1.9:4200/
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.9
Cookie: access_token=eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX25hbWUiOiJhZG1pbiIsInNjb3BlIjpbIm9wZW5pZCJdLCJleHAiOjE1NDAyMDI3MTIsImlhdCI6MTU0MDIwMDkxMiwiYXV0aG9yaXRpZXMiOlsiUk9MRV9BRE1JTiIsIlJPTEVfVVNFUiJdLCJqdGkiOiJhMjU2N2FjNS01ZjhjLTQ3OGUtOGI3NS1lMTI1NzFlMTQ0N2QiLCJjbGllbnRfaWQiOiJ3ZWJfYXBwIn0.I5UOoVxrrJwa140FRJDSIxuSeySMnHdHJv8rIBPZmGi-jyobKbea7AjZ6dqwblPx3mMXnAqPlp8XxTeDRvRe9BEgHzRxvOmz5Pp3IC1RetLdwjcmM2qKCcUlagkita3GwEpsOCfLWIaCXBufLycmpu1-96gUF-FLqFvYPQnNfK_JZkrGesu33UUKDkEj_PbC8kxK2toLh8PNo7IJ16uhKLdZi7i9oqx2QBCMtYc9uqiPpv-NTbhUZfYnoigG8Tphcr6GtfQJ53eK4NBFStIOpAJ-b6LSixbaCA1W7_x2QHJ-gxp-iscGgXcdouDlXaKMtE-D6IfDzPwQE7MoeAhKsA; session_token=eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX25hbWUiOiJhZG1pbiIsInNjb3BlIjpbIm9wZW5pZCJdLCJhdGkiOiJhMjU2N2FjNS01ZjhjLTQ3OGUtOGI3NS1lMTI1NzFlMTQ0N2QiLCJleHAiOjE1NDA4MDU3MTIsImlhdCI6MTU0MDIwMDkxMiwiYXV0aG9yaXRpZXMiOlsiUk9MRV9BRE1JTiIsIlJPTEVfVVNFUiJdLCJqdGkiOiI3NDBjMDAxOC1mNmEwLTQ5NzUtYjg4OS0yMzUxNGI5ZGIwOTEiLCJjbGllbnRfaWQiOiJ3ZWJfYXBwIn0.ZE8NLJIie45Ibh6dn1tlpwOmLuf5Lw-ER75cdzNsMDCpy6CPRSIIkBr0gaUJEvLlKQgqOS_LsD5cJ3ugdjYBugN4ye3s3uIccDhn3b0y5Ek1NNPyZSK0b7wWSDIhhdgmCVAmBN5ZKAWr5iNmMzSMpww34ahv8XQ8Q1zJNUUxVrdcXL20PEnEQvSP1fnh8vhzheJGNN7PXPSS2LMOmY515yhIAT8psNluOpOQ38g86IQy-p8CWnUZsNjhfXIxo6Zu9Y9T_witSKuDIeIQ7wAfB_gExPOSIDHaW5XFjSqDfpHIFizBLiXdDDpnAKvNEIHsojMVbP9Z0hRDYFOcQxQ7qg

角度边代码

import { Component, OnInit, NgZone } from '@angular/core';
import { Observable } from 'rxjs';
import { Http, Headers, RequestOptions, Response, URLSearchParams } from '@angular/http';

@Component({
    selector: 'app-admin-dashboard-content',
    templateUrl: './admin-dashboard-content.component.html',
    styleUrls: ['./admin-dashboard-content.component.css']
})

export class AdminDashboardContentComponent implements OnInit {
    myData: any;
    constructor(private admiDashboardServiceMain: admiDashboardServiceMain,
        private zone: NgZone) {
        this.connect();
    }
    ngOnInit() { }
    connect(): void {
        let headers = new Headers({ 'accept': 'text/event-stream;charset=UTF-8' });
        let options = new RequestOptions({ headers: headers, withCredentials: true });
        let source = new EventSource('http://192.168.1.9:8080/proxta/api/student-answered-correctly-by-que_nft', options)
        source.addEventListener('message', message => {
            console.log(message)
        });
    }
}
  • 我现在只是控制台输出。感谢帮助,谢谢

最佳答案

当 Angular(版本 10)发送 EventSource 请求时,使用请求 header :Accept: text/event-stream。

如果您的服务器无法产生此类输出,服务器将拒绝该请求。使用 Spring Boot,请求甚至不会到达您的 Controller 代码。

查看我的(错误的)Spring 启动代码:

@GetMapping(value = "/flux/{api}", produces = MediaType.APPLICATION_STREAM_JSON_VALUE)
public Flux<Movie> getMovieFlux(
        @PathVariable String api, @RequestParam("title") String title) {
    return service.getMovieFlux(title, api);
}

我只需要更改它的“生产”部分:

@GetMapping(value = "/flux/{api}", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
public Flux<Movie> getMovieFlux(
        @PathVariable String api, @RequestParam("title") String title) {
    return service.getMovieFlux(title, api);
}

或者与ServerSentEvent相同:

@GetMapping(value = "/flux/{api}")
public Flux<ServerSentEvent<Movie>> getMovieFlux(
        @PathVariable String api, @RequestParam("title") String title) {
    return service.getMovieFlux(title, api)
            .map(movie -> ServerSentEvent.<Movie>builder().build());
}

关于spring - 服务器发送事件错误 : 406 (Not Acceptable) in Angular5 + Spring App,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52926682/

相关文章:

java - 为什么从已满的队列中发送 Spring AMQP 消息会出现延迟?

java - Mockito 与 JavaMailSender

angular6 - 如何在 ng-select 中搜索多个字段?

angular - 可观察的 forkjoin 订阅类型

angular - 可以激活守卫并使用带有 angular 5 的 observables

android - 了解 RxJava 基础知识

java - Spring集成应用和缓存

java.lang.ClassCastException : class org. springframework.security.core.userdetails.User 无法转换为类

angular - 在 Angular 4/5 中编译动态 HTML——类似于 Angular JS 中的 $compile

javascript - Angular 5 嵌套 *ngFor-Loop 与 block