Bhagvat Lande
Bhagvat Lande

Reputation: 1480

Server Sent Events Error : 406 (Not Acceptable) in Angular5 + Spring App

I am working with Angular5 application , where i need to show Real-time data on dashboard.our backend is written in spring(v4.x) which having api which sends results when any server event is generated.

But when i am calling this api in Angular app which always gives me

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

Response Header (Copied from network)

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

Request 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

Angular Side Code

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)
        });
    }
}

Upvotes: 6

Views: 4880

Answers (2)

PeterB
PeterB

Reputation: 1091

When Angular (version 10) sends request for EventSource, uses the Request header: Accept: text/event-stream.

If your server can not produce this type of output, the server will refuse the request. With spring boot, the request will not even reach your controller code.

See my (bad) Spring boot code:

@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);
}

I only needed to change the "produce" part of it:

@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);
}

Or the same with 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());
}

Upvotes: 2

ceaserg
ceaserg

Reputation: 106

I don't believe the EventSource API allows for sending HTTP headers. Try just creating a new event source object like this:

let source = new EventSource('http://192.168.1.9:8080/proxta/api/student-answered-correctly-by-que_nft', {withCredentials: true});

Upvotes: 1

Related Questions