5

jquery-fileupload を使用して、ユーザーがファイルを外部サービスにアップロードできるようにしています (具体的には Cloudinary です)。

<input type='file' name='file' class='cloudinary-fileupload' 
  data-url='https://api.cloudinary.com/v1_1/wya/auto/upload' />
<script>
  $('.cloudinary-fileupload').fileupload();
</script>

これは外部ターゲットであるため、ブラウザーは CORS 要求を開始します。ただし、ブラウザーが CORS プリフライト リクエストを先頭に追加していることに気付きました。 http://www.html5rocks.com/en/tutorials/cors/は、プリフライト リクエストがいつトリガーされ、いつトリガーされないかについて、非常に優れた洞察を提供します。私の知る限り、私のリクエストは CORS の単純なリクエストであるというすべての基準を満たしています (セクション「CORS リクエストのタイプ」を参照)。

外部サービスに送信されるファイルアップロード リクエスト:

POST /v1_1/wya/image/upload HTTP/1.1
Host: api.cloudinary.com
Connection: keep-alive
Content-Length: 22214
Accept: */*
Origin: http://wya.herokuapp.com
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/32.0.1700.107 Safari/537.36
Content-Type: multipart/form-data; boundary=----WebKitFormBoundarym73rCIa6t8eTNkTa
Referer: http://wya.herokuapp.com/
Accept-Encoding: gzip,deflate,sdch
Accept-Language: sv-SE,sv;q=0.8,en-US;q=0.6,en;q=0.4,de;q=0.2

ファイル アップロード リクエストの前に外部サービスに送信される追加のプリフライトリクエスト:

OPTIONS /v1_1/wya/image/upload HTTP/1.1
Host: api.cloudinary.com
Connection: keep-alive
Access-Control-Request-Method: POST
Origin: http://wya.herokuapp.com
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/32.0.1700.107 Safari/537.36
Access-Control-Request-Headers: accept, content-type
Accept: */*
Referer: http://wya.herokuapp.com/
Accept-Encoding: gzip,deflate,sdch
Accept-Language: sv-SE,sv;q=0.8,en-US;q=0.6,en;q=0.4,de;q=0.2

この余分なプリフライト リクエストを回避する方法はありますか? 私が見る限り、ファイル アップロード リクエストは、Content-Type multipart/form-data と単純なリクエスト HTTP ヘッダーのみを含む HTTP POST であるため、CORS の単純なリクエストです。


余分なプリフライト リクエストを削除したい理由は、Cloudinary がファイル アップロードへの応答として HTTP 302/304 リダイレクトを送信するためです。ブラウザはこれらのリダイレクトに従いません。Chrome は次のメッセージで失敗します。

XMLHttpRequest cannot load https://api.cloudinary.com/v1_1/wya/image/upload. 
The request was redirected to 'http://wya.herokuapp.com/upload?bytes=21534&created_at=2014-02-12T09%3A04%3…d5b62ebb92b9236e5be6d472df242d016&type=upload&version=1392195882&width=723', 
which is disallowed for cross-origin requests that require preflight. 
4

2 に答える 2

10

問題は、Cloudinary へのリクエストで XHR ヘッダーが送信されないため、Cloudinary が JSON を返す代わりにリダイレクト (IE フォールバック) することです。これは通常、ウィジェットの初期化が不適切なために発生します。$('.cloudinary-fileupload').fileupload()これは含まれている Javascript によって行われるため、通常は自分自身を呼び出す必要はありません。ウィジェットを手動で初期化する必要がある場合は、 を使用してください$('.cloudinary-fileupload').cloudinary_fileupload()

于 2014-02-13T02:54:12.903 に答える
0

JavaScript fetch に興味のある方へ。cloudinary アップロードで機能するコードは次のとおりです。以下は反応コンポーネント用ですが、フェッチはほぼすべての JavaScript コードで機能するはずです。nginxserver も構成していますが、それはプロキシパスのみを行います。注意すべきポイントは、FormData オブジェクトを使用して、upload_preset と file パラメータを設定することです。ヘッダーを避けて、簡単な投稿を行います。

export const uploadImg = (id, key, blob) => {
const controller = new AbortController();
const frmData = new FormData();
const apptype = blob.type;

frmData.set('upload_preset', '<upload_preset_name>');
frmData.set('public_id', id + '_' + key);
frmData.set('tags', id);
frmData.set('file', blob, key);
frmData.set('folder', '<folder_name>');

// ヘッダーは使用されていないことに注意してください。//うまくいかなかったヘッダーを使用してみましたこれらのヘッダーをコメントアウトするとうまくいきました。

/* 
     const headers = new Headers({
        'Access-Control-Request-Headers':'Accept, Content-Type',
        'Accept': 'multipart/form-data',
        'Content-Type': 'multipart/form-data',        

    });  */


const uri = 'https://api.cloudinary.com/v1_1/<cloud_name>/image/upload';
const req = new Request(uri, {
    signal: controller.signal,
    method: 'POST',
    // mode:'no-cors',
    // headers: headers,
    body: frmData,
});

return fetch(req);enter code here
}

Cloudinary には、curl、fetch、axios の標準的なベスト プラクティス コード サンプルが実際に含まれている必要があります。開発者は、cors 関連の問題をすべて把握して対処しようとして、多くの時間を無駄にすることになります。

于 2020-02-10T05:20:27.517 に答える