web-dev-qa-db-ja.com

hapi.js CorsプレフライトがAccess-Control-Allow-Originヘッダーを返さない

(Dropzone js)を使用してajaxファイルをアップロードしています。ファイルを私のhapiサーバーに送信します。ブラウザがプリフライトオプションメソッドを送信することに気づきました。しかし、私のhapiサーバーは正しい応答ヘッダーを送信しないようですので、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.

これはhapi jsルートハンドラです

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

私の理解では、hapi jsは戦前(OPTIONS)リクエストからすべてのcorsヘッダーを送信する必要があります。それがそうではない理由をカントは理解します

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

前もって感謝します

11
kweku360

ハピcors: trueは、 hapiのデフォルトのホワイトリスト の外に追加のリクエストヘッダーがある場合を含むいくつかのケースを除いて、すべてのドメインからのCORSリクエストを許可するワイルドカードルールです。

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

ルートオプションのAPIドキュメントのcorsオプションセクションを参照

headers-許可されたヘッダーの文字列配列( 'Access-Control-Allow-Headers')。デフォルトは['Accept', 'Authorization', 'Content-Type', 'If-None-Match']

additionalHeaders-ヘッダーへの追加ヘッダーの文字列配列。これを使用して、デフォルトのヘッダーを維持します。

あなたの問題は、Dropzoneがこのリストにないファイルのアップロードと共にいくつかのヘッダーを送信することです:

  • x-requested-with(上のヘッダーにはありませんが、私に送信されました)
  • cache-control

物事を機能させるには2つのオプションがあり、サーバーまたはクライアントのいずれかで何かを変更する必要があります。

オプション1-追加のヘッダーをホワイトリストに登録します。

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

        ...
    }
});

オプション2-これらの余分なヘッダーを送信しないようにdropzoneに指示する

彼らの設定ではまだ可能ではありませんが、それを許可する保留中のPRがあります: https://github.com/enyo/dropzone/pull/685

17
Matt Harrison

上記で私の問題を完全に解決できなかったので、これに私の2セントを追加したいと思います。

Hapi-Serverをlocalhost:3300で起動しました。次に、localhost:80からhttp://localhost:3300/にCORSをテストするように要求しました。これはchromeにつながります。

リクエストされたリソースに「Access-Control-Allow-Origin」ヘッダーがありません

(これはまったく真実ではありませんでした)。 Then XHR-Requestを変更して、URLをHapiJS内に実際に作成したURL(私の場合はhttp://localhost:3300/api/test)にURLをフェッチしました。 これでうまくいきました

この問題を回避するために、HapiJSに「キャッチオール」ルートを作成しました(組み込みの404キャッチを回避するため)。

const Boom = require('Boom'); //You can require Boom when you have hapi

Route({
  method: '*',
  path: '/{any*}',
  handler: function(request, reply) {
    reply(Boom.notFound());
  }
})
0
androidavid