Hapi.js Cors Doesn't Return Before Flight Access-Control-Allow-Origin

I have ajax file upload using (Dropzone js). which sends the file to my hapi server. I realized that the browser sends SPECIFICATIONS OF PRELIMINARY OPTIONS. but my hapi server doesn't seem to send the correct response headers, so I get errors on chrome. here is the error i get chrome

XMLHttpRequest cannot load http://localhost:3000/uploadbookimg. Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:4200' is therefore not allowed access. 

this is the hapi js route handler

 server.route({ path: '/uploadbookimg', method: 'POST', config: { cors : true, payload: { output: 'stream', parse: true, allow: 'multipart/form-data' }, handler: require('./books/webbookimgupload'), } }); 

In my understanding, hapi js should send all the cors headers from the Pre-fight (OPTIONS) request. I can not understand why it is not

Network request / response from chrome

 **General** Request Method:OPTIONS Status Code:200 OK Remote Address:127.0.0.1:3000 **Response Headers** view parsed HTTP/1.1 200 OK content-type: application/json; charset=utf-8 cache-control: no-cache vary: accept-encoding Date: Wed, 27 Apr 2016 07:25:33 GMT Connection: keep-alive Transfer-Encoding: chunked **Request Headers** view parsed OPTIONS /uploadbookimg HTTP/1.1 Host: localhost:3000 Connection: keep-alive Pragma: no-cache Cache-Control: no-cache Access-Control-Request-Method: POST Origin: http://localhost:4200 User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.87 Safari/537.36 Access-Control-Request-Headers: accept, cache-control, content-type Accept: */* Referer: http://localhost:4200/books/upload Accept-Encoding: gzip, deflate, sdch Accept-Language: en-US,en;q=0.8 

Thanks in advance

+7
javascript cors hapijs
source share
2 answers

hapi cors: true is a wildcard rule that resolves CORS requests from all domains, except in a few cases, including additional request headers outside of hapi default whitelist

["accept", "authorization", "content-type", "if-none-match", "origin"]

See the cors section in the API docs for route parameters :

headers - an array of allowed header lines ("Access-Control-Allow-Headers"). By default ['Accept', 'Authorization', 'Content-Type', 'If-None-Match'] .

additionalHeaders - an array of strings from extra headers to headers. Use this to keep the default headers.

Your problem is that Dropzone sends a couple of headers along with downloading files that are not on this list:

  • x-requested-with (not in your headers above, but was sent to me)
  • cache-control

You have two options, to make everything work, you need to change something on the server or client:

Option 1 - Whitelist additional headers:

 server.route({ config: { cors: { origin: ['*'], additionalHeaders: ['cache-control', 'x-requested-with'] } }, method: 'POST', path: '/upload', handler: function (request, reply) { ... } }); 

Option 2 - tell dropzone not to send these extra headers

It is not possible through their configuration yet, but there is a pending PR there to allow this: https://github.com/enyo/dropzone/pull/685

+12
source share

I want to add my 2 cents to this, as the above did not completely solve the problem in my case.

I started my Hapi server in localhost:3300 . Then I asked from localhost:80 to http://localhost:3300/ to check CORS. This causes the chrome to still block the source, as he said that

No header "Access-Control-Allow-Origin" is present in the requested resource

(which is not entirely true). Then I modified the XHR-Request to get the URL of the URL for which I actually created a route inside HapiJS, which - in my case - was http://localhost:3300/api/test . It worked .

To overcome this problem, I created an all-all route in HapiJS (to overdo it with the built-in 404 catch).

 const Boom = require('Boom'); //You can require Boom when you have hapi Route({ method: '*', path: '/{any*}', handler: function(request, reply) { reply(Boom.notFound()); } }) 
0
source share

All Articles