Search code examples
angulartypescripthttpsngrok

Http failure during parsing Angular with ngrok


I'm building an app to track drinks' pricing during a stock market party. Everything was working smoothly when testing using localhost via Chrome, but I now tried port forwarding for both the NestJS backend and Angular frontend via ngrok.

I've narrowed the problem down to the Angular frontend as my requests aren't coming in to ngrok.

In the frontend, the DrinksService requests all drinks from the backend

export class DrinksService {
  constructor(private http: HttpClient, private localService: LocalService) { }

  private url: string = 'https://7a4c-81-241-237-61.ngrok-free.app/drinks'//'http://localhost:3000/drinks';
  drinks: Drink[] = [];

  getDrinks(): Observable<Drink[]> {
    console.log('Getting drinks from backend');
    return this.http.get<Drink[]>(this.url);
  }

  getDrink(name: string): Observable<Drink> {
    console.log('Getting drink: ' + name)
    return this.http.get<Drink>(this.url + '/' + name)
  }

  getDrinksByGroup(): Observable<{alcohols: Drink[], notAlcohols: Drink[] }> {
    return this.getDrinks().pipe(map(drinks => {
      const alcoholDrinks: Drink[] = [];
      const notAlcoholDrinks: Drink[] = [];

      drinks.forEach(drink => {
        if(drink.alcohol) {
          let localAlcohols: Drink[] = JSON.parse(this.localService.getData('alcohols'));
          if(localAlcohols.length !== 0 && localAlcohols.length !== undefined) {
            let localAlcohol: Drink = localAlcohols.find((localAlcohol) => {
              return drink.name === localAlcohol.name;
            }) || drink;
            drink.numberInOrder = localAlcohol.numberInOrder;
            alcoholDrinks.push(drink);
          } else {
            alcoholDrinks.push(drink)
          }
        } else {
          let localNonAlcohols: Drink[] = JSON.parse(this.localService.getData('nonAlcohols'));
          if(localNonAlcohols.length !== 0 && localNonAlcohols.length !== undefined) {
            let localNonAlcohol: Drink = localNonAlcohols.find((localNonAlcohol) => {
              return drink.name === localNonAlcohol.name;
            }) || drink;
            drink.numberInOrder = localNonAlcohol.numberInOrder;
            notAlcoholDrinks.push(drink)
          } else {
            notAlcoholDrinks.push(drink)
          }
        }
      });
      return { alcohols: alcoholDrinks, notAlcohols: notAlcoholDrinks };
    }));
  }
.
.
.
}

I can access the url in my browser or Postman without issue, getting a correct JSON response (below).

[{"name":"Pintje","alcohol":true,"startPrice":1.8,"minPrice":1.1,"maxPrice":5,"numberInOrder":0,"currentPrice":1.8,"numberSold":0,"soldOut":false,"beurscrash":{"active":false}}]

When trying to run the getDrinks() method though, it gives me an Http error, which only happens since I've changed it to access ngrok instead of localhost. I can't quite figure out why this doesn't work.

Http Error

HttpErrorResponse
error
: 
error
: 
SyntaxError: Unexpected token '<', "<!DOCTYPE "... is not valid JSON at JSON.parse (<anonymous>) at XMLHttpRequest.onLoad (https://fb36-81-241-237-61.ngrok-free.app/vendor.js:40970:39) at _ZoneDelegate.invokeTask (https://fb36-81-241-237-61.ngrok-free.app/polyfills.js:7603:171) at https://fb36-81-241-237-61.ngrok-free.app/vendor.js:65262:49 at AsyncStackTaggingZoneSpec.onInvokeTask (https://fb36-81-241-237-61.ngrok-free.app/vendor.js:65262:30) at _ZoneDelegate.invokeTask (https://fb36-81-241-237-61.ngrok-free.app/polyfills.js:7603:54) at Object.onInvokeTask (https://fb36-81-241-237-61.ngrok-free.app/vendor.js:65564:25) at _ZoneDelegate.invokeTask (https://fb36-81-241-237-61.ngrok-free.app/polyfills.js:7603:54) at Zone.runTask (https://fb36-81-241-237-61.ngrok-free.app/polyfills.js:7405:37) at ZoneTask.invokeTask [as invoke] (https://fb36-81-241-237-61.ngrok-free.app/polyfills.js:7680:26)
message
: 
"Unexpected token '<', \"<!DOCTYPE \"... is not valid JSON"
stack
: 
"SyntaxError: Unexpected token '<', \"<!DOCTYPE \"... is not valid JSON\n    at JSON.parse (<anonymous>)\n    at XMLHttpRequest.onLoad (https://fb36-81-241-237-61.ngrok-free.app/vendor.js:40970:39)\n    at _ZoneDelegate.invokeTask (https://fb36-81-241-237-61.ngrok-free.app/polyfills.js:7603:171)\n    at https://fb36-81-241-237-61.ngrok-free.app/vendor.js:65262:49\n    at AsyncStackTaggingZoneSpec.onInvokeTask (https://fb36-81-241-237-61.ngrok-free.app/vendor.js:65262:30)\n    at _ZoneDelegate.invokeTask (https://fb36-81-241-237-61.ngrok-free.app/polyfills.js:7603:54)\n    at Object.onInvokeTask (https://fb36-81-241-237-61.ngrok-free.app/vendor.js:65564:25)\n    at _ZoneDelegate.invokeTask (https://fb36-81-241-237-61.ngrok-free.app/polyfills.js:7603:54)\n    at Zone.runTask (https://fb36-81-241-237-61.ngrok-free.app/polyfills.js:7405:37)\n    at ZoneTask.invokeTask [as invoke] (https://fb36-81-241-237-61.ngrok-free.app/polyfills.js:7680:26)"
[[Prototype]]
: 
Error
constructor
: 
ƒ SyntaxError()
message
: 
""
name
: 
"SyntaxError"
[[Prototype]]
: 
Object
text
: 
"<!DOCTYPE html>\n<html class=\"h-full\" lang=\"en-US\" dir=\"ltr\">\n  <head>\n    <link rel=\"preload\" href=\"https://cdn.ngrok.com/static/fonts/euclid-square/EuclidSquare-Regular-WebS.woff\" as=\"font\" type=\"font/woff\" crossorigin=\"anonymous\" />\n    <link rel=\"preload\" href=\"https://cdn.ngrok.com/static/fonts/euclid-square/EuclidSquare-RegularItalic-WebS.woff\" as=\"font\" type=\"font/woff\" crossorigin=\"anonymous\" />\n    <link rel=\"preload\" href=\"https://cdn.ngrok.com/static/fonts/euclid-square/EuclidSquare-Medium-WebS.woff\" as=\"font\" type=\"font/woff\" crossorigin=\"anonymous\" />\n    <link rel=\"preload\" href=\"https://cdn.ngrok.com/static/fonts/euclid-square/EuclidSquare-Semibold-WebS.woff\" as=\"font\" type=\"font/woff\" crossorigin=\"anonymous\" />\n    <link rel=\"preload\" href=\"https://cdn.ngrok.com/static/fonts/euclid-square/EuclidSquare-MediumItalic-WebS.woff\" as=\"font\" type=\"font/woff\" crossorigin=\"anonymous\" />\n    <link rel=\"preload\" href=\"https://cdn.ngrok.com/static/fonts/ibm-plex-mono/IBMPlexMono-Text.woff\" as=\"font\" type=\"font/woff\" crossorigin=\"anonymous\" />\n    <link rel=\"preload\" href=\"https://cdn.ngrok.com/static/fonts/ibm-plex-mono/IBMPlexMono-TextItalic.woff\" as=\"font\" type=\"font/woff\" crossorigin=\"anonymous\" />\n    <link rel=\"preload\" href=\"https://cdn.ngrok.com/static/fonts/ibm-plex-mono/IBMPlexMono-SemiBold.woff\" as=\"font\" type=\"font/woff\" crossorigin=\"anonymous\" />\n    <link rel=\"preload\" href=\"https://cdn.ngrok.com/static/fonts/ibm-plex-mono/IBMPlexMono-SemiBoldItalic.woff\" as=\"font\" type=\"font/woff\" crossorigin=\"anonymous\" />\n    <meta charset=\"utf-8\">\n    <meta name=\"author\" content=\"ngrok\">\n    <meta name=\"description\" content=\"ngrok is the fastest way to put anything on the internet with a single command.\">\n    <meta name=\"robots\" content=\"noindex, nofollow\">\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n    <link id=\"style\" rel=\"stylesheet\" href=\"https://cdn.ngrok.com/static/css/error.css\">\n    <noscript>You are about to visit 7a4c-81-241-237-61.ngrok-free.app, served by 81.241.237.61. This website is served for free through ngrok.com. You should only visit this website if you trust whoever sent the link to you. (ERR_NGROK_6024)</noscript>\n    <script id=\"script\" src=\"https://cdn.ngrok.com/static/js/error.js\" type=\"text/javascript\"></script>\n  </head>\n  <body class=\"h-full\" id=\"ngrok\">\n    <div id=\"root\" data-payload=\"eyJjZG5CYXNlIjoiaHR0cHM6Ly9jZG4ubmdyb2suY29tLyIsImNvZGUiOiI2MDI0IiwiaG9zdHBvcnQiOiI3YTRjLTgxLTI0MS0yMzctNjEubmdyb2stZnJlZS5hcHAiLCJtZXNzYWdlIjoiWW91IGFyZSBhYm91dCB0byB2aXNpdCA3YTRjLTgxLTI0MS0yMzctNjEubmdyb2stZnJlZS5hcHAsIHNlcnZlZCBieSA4MS4yNDEuMjM3LjYxLiBUaGlzIHdlYnNpdGUgaXMgc2VydmVkIGZvciBmcmVlIHRocm91Z2ggbmdyb2suY29tLiBZb3Ugc2hvdWxkIG9ubHkgdmlzaXQgdGhpcyB3ZWJzaXRlIGlmIHlvdSB0cnVzdCB3aG9ldmVyIHNlbnQgdGhlIGxpbmsgdG8geW91LiIsInNlcnZpbmdJUCI6IjgxLjI0MS4yMzcuNjEiLCJ0aXRsZSI6Ik9LIn0=\"></div>\n  </body>\n</html>\n"
[[Prototype]]
: 
Object
headers
: 
HttpHeaders {normalizedNames: Map(0), lazyUpdate: null, lazyInit: ƒ}
message
: 
"Http failure during parsing for https://7a4c-81-241-237-61.ngrok-free.app/drinks"
name
: 
"HttpErrorResponse"
ok
: 
false
status
: 
200
statusText
: 
"OK"
url
: 
"https://7a4c-81-241-237-61.ngrok-free.app/drinks"
[[Prototype]]
: 
HttpResponseBase

For completeness, the backend call looks like this in NestJS

@Controller('drinks')
export class DrinksController {
    constructor(private drinksService: DrinksService, private salesHistoryService: SalesHistoryService) {}
    private readonly logger = new Logger(DrinksController.name);



    @Get()
    async getDrinks(@Res() res: Response) {
        this.logger.log("GET: getDrinks()")
        res.set('Access-Control-Allow-Origin', '*');
        res.set
        res.send(this.drinksService.getAllDrinks());
    }
.
.
.
}

Solution

  • The response you get contains a warning, with code ERR_NGROK_6024, which can be solved by adding ngrok-skip-browser-warning header.

    Source: ngrok have added a new intersitial page warning about using a free account (ERR_NGROK_6024)

    So try adding the header. You could create a method which will be called in each request. For example:

    // refactor as needed..
    private getHeaders() {
      const headers = new HttpHeaders({
        'ngrok-skip-browser-warning':  '69420'
      });
      return {headers};
    }
    
    
    //...
    
    this.http.get<Drink[]>(this.url, this.getHeaders())