0

I have an angular application which is querying a node/express backend endpoint every 5 seconds. However, occasionally i am getting a cors error.

Usecase

  1. A user creates a transaction. The transaction gets added to the database with the status of "Pending"
  2. The frontend periodically queries the database until the status has been updated to "Completed". So it can retrieve the results.

Angular

Every 5 seconds i am doing a http get request

   const url = 'https://<removed>.com/api/v1/transactions/' + transactionId;

    interval(5000)
        .pipe(
            switchMap(() => this.httpClient.get(url)),
            tap((response: any) => {
                this.summary = response;
            }),
            takeWhile((response: any) => response.data['status'] !== 'Completed'),
    ).subscribe();

}

The first request is fine, then i get the following error on the next request.

Failed to load https://"".com/api/v1/transactions/f3debad2-a830-4168-9a03-475389dae7e0: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:4200' is therefore not allowed access. The response had HTTP status code 502.

Cross-Origin Read Blocking (CORB) blocked cross-origin response https://"".com/api/v1/transactions/f3debad2-a830-4168-9a03-475389dae7e0 with MIME type text/html. See https://www.chromestatus.com/feature/5629709824032768 for more details.

Again this only happens sometimes, other times i can make as many requests i want with 200 responses.

Node

I set CORS in my backend.

  app.use(cors());

Note

I'm not sure if its a complete server-side issue. This is a random edge case. All my other API requests including POST requests work fine.

Infact before it starts the interval of 5 seconds to check if the results are ready, it posts to endpoint on the same domain, with no problems.

I have done 10 test cases, each test will query the endpoint 3-4 times (usuaully takes this long before the results are ready/complete). All 10 test cases could be fine then the 11th might have this problem.

sideshowbarker
  • 81,827
  • 26
  • 193
  • 197
Kay
  • 17,906
  • 63
  • 162
  • 270
  • where do you host your angular? is it http or https? – mehta-rohan Aug 24 '18 at 16:16
  • 2
    If it's coming back with a 502, sounds like the error is in your backend, not in Angular. Where / how are you hosting / running the backend? – user184994 Aug 24 '18 at 16:16
  • @mehta-rohan hosted on https, backend also https – Kay Aug 24 '18 at 16:17
  • Have you tried to make the polling last longer? Maybe your request sometimes takes more time than you expected – Julian Torregrosa Aug 24 '18 at 16:18
  • @user184994 containerised in docker image hosted on amazon ec2. – Kay Aug 24 '18 at 16:18
  • @jdtorregrosas No ive not. Thank you for this suggestion. Your saying it might take more than 5 seconds to poll the backend? Even if it does why would that throw a cors error? Could i improve the angular code to catch that somehow and retry? – Kay Aug 24 '18 at 16:20
  • If you check the metrics for your EC2 instance, is it running low on resources at all? High CPU usage? – user184994 Aug 24 '18 at 16:24
  • @user184994 unfortunately, im not able to check. I will ask someone on monday to look into that. Could you explain why that might cause a cors issue? – Kay Aug 24 '18 at 16:24
  • The reason you're seeing the CORS issue is that there is an error between your EC2 and the express app (hence the 502 error). This means that your CORS headers aren't added. One reason that the backend may be unavailable is if your EC2 instance is running out of resources – user184994 Aug 24 '18 at 16:26
  • can you show us you front-end file? It happened with us due to wrong script tags. – mehta-rohan Aug 24 '18 at 16:46
  • @mehta-rohan its an angular app, i can't show you the entire app. – Kay Aug 28 '18 at 08:05

2 Answers2

0

I don't know if you solved your problem during these 2 years. But yesterday i encounter the same error.

At first i thought that was CORS problems too, after i saw the loss of headers in the second call and the "keep-alive" tag in the headers, i can't found nothing about my promise so i try to close the automatic 'keep-alive' connexion by waiting some times.

I don't use the takeWhile to make the loop i prefer the for loop because it possible to use the await function in it.

for(const list of lists){
    await this.httpClient.get(url).toPromise();
    await this.delay(500);
}

delay(ms: number) {
    return new Promise( resolve => setTimeout(resolve, ms) );
}

I try with 100 and 200ms but it doesn't works for me.

I hope it will helps you.

-2
app.use(function(req, res, next) {
  res.setHeader('Access-Control-Allow-Origin', '*');
  res.setHeader('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE,OPTIONS');
  res.setHeader('Access-Control-Allow-Headers', 'Content-Type');
  res.setHeader('Access-Control-Expose-Headers','Content-Type,expire');
 next();
});

Try this one in your server. If you want to pass extra header parameter you need to add those variable in res.setHeader('Access-Control-Allow-Headers', 'Content-Type , token'); but remember don't user '-' in the variable name.

Jit Dhar
  • 192
  • 10
  • Am i not doing that already with the use of the npm cors package? What in your code is different that would solve this problem? Take into account making requests works fine with other endpoints and this one except when making it periodically to the same one with the above angular code https://www.npmjs.com/package/cors – Kay Aug 24 '18 at 16:21
  • Some time package failed to deliver i also faced this issue and solved that in this way and works for me. – Jit Dhar Aug 24 '18 at 16:28
  • @Kay cors() doesn't guarantee you all the settings. you have to explicitly define all of them – mehta-rohan Aug 24 '18 at 17:07
  • no issue, just check your script tags if they are at right place or not – mehta-rohan Aug 28 '18 at 08:06