検索
ホームページウェブフロントエンドjsチュートリアルクロスドメインリソース共有CORS詳細説明_JavaScriptスキル

ブラウザがクロスオリジンサーバーに対して XMLHttpRequest リクエストを行うことができるため、AJAX は同じオリジンからのみ使用できるという制限が克服されます。

この記事では、CORS の内部メカニズムを詳しく紹介します。

(写真の説明: アラブ首長国連邦、アル・アインのオアシスパークで撮影)

1. はじめに

CORS にはブラウザとサーバーの両方のサポートが必要です。現在、すべてのブラウザがこの機能をサポートしており、IE ブラウザは IE10 よりも古いものにすることはできません。

CORS 通信プロセス全体はブラウザによって自動的に完了し、ユーザーの参加は必要ありません。開発者にとって、同じソースからの CORS 通信と AJAX 通信に違いはなく、コードはまったく同じです。ブラウザーが AJAX リクエストがクロスオリジンであることを検出すると、追加のヘッダー情報が自動的に追加され、追加のリクエストが行われることもありますが、ユーザーはそれを感じません。

したがって、CORS 通信を実現するための鍵はサーバーです。サーバーが CORS インターフェイスを実装している限り、クロスオリジン通信が可能です。

2. 2 種類のリクエスト

ブラウザは、CORS リクエストを 2 つのカテゴリ (単純なリクエストとそれほど単純ではないリクエスト) に分類します。

以下の2つの条件を同時に満たしていれば簡単なリクエストです。

(1)リクエスト方法は以下の3つの方法のいずれかです。

ヘッドポスト

(2) HTTP ヘッダー情報は次のフィールドを超えません:

AcceptAccept-LanguageContent-LanguageLast-Event-IDContent-Type: 3 つの値に制限application/x-www-form-urlencodedmultipart/form-datatext/plain

上記 2 つの条件を同時に満たさないリクエストは、非単純リクエストとみなされます。

ブラウザはこれら 2 つのリクエストを異なる方法で処理します。

3. 簡単なリクエスト 3.1 基本的なプロセス

単純なリクエストの場合、ブラウザは CORS リクエストを直接発行します。具体的にはヘッダ情報にOriginフィールドを追加することです。

以下は例です。ブラウザは、このクロスオリジン AJAX リクエストが単純なリクエストであることを認識し、ヘッダー情報に Origin フィールドを自動的に追加します。

GET /cors HTTP/1.1Origin: http://api.bob.comHost: api.alice.comAccept-Language: en-USConnection: keep-aliveUser-Agent: Mozilla/5.0...

上記のヘッダー情報の Origin フィールドは、このリクエストの送信元 (プロトコル + ドメイン名 + ポート) を示すために使用されます。サーバーは、この値に基づいてリクエストに同意するかどうかを決定します。

Originで指定されたソースが許可範囲内にない場合、サーバーは通常の HTTP 応答を返します。ブラウザは、この応答のヘッダー情報に Access-Control-Allow-Origin フィールドが含まれていないことを検出すると (詳細は以下を参照)、何か問題が発生したことを認識してエラーをスローします。これは、XMLHttpRequest コールバック関数によってキャッチされます。 >。 HTTP 応答のステータス コードが 200 である可能性があるため、このエラーはステータス コードでは特定できないことに注意してください。 onerror

で指定されたドメイン名が許可の範囲内にある場合、サーバーから返される応答にはさらにいくつかのヘッダー情報フィールドが含まれます。 Origin

Access-Control-Allow-Origin: http://api.bob.comAccess-Control-Allow-Credentials: trueAccess-Control-Expose-Headers: FooBarContent-Type: text/html; charset=utf-8

上記のヘッダー情報の中には、CORS リクエストに関連する 3 つのフィールドがあり、すべて

で始まります。 Access-Control-

(1) アクセス制御-許可-Origin

このフィールドは必須です。その値は、リクエスト中の

フィールドの値、または任意のドメイン名からのリクエストが受け入れられることを示す Origin のいずれかです。 *

(2) アクセス制御許可資格情報

このフィールドはオプションです。その値は、Cookie の送信を許可するかどうかを示すブール値です。デフォルトでは、Cookie は CORS リクエストに含まれません。

に設定すると、サーバーがリクエストに Cookie を含めてサーバーに送信することを明示的に許可します。この値は true にのみ設定できます。サーバーがブラウザーに Cookie を送信させたくない場合は、このフィールドを削除してください。 true

(3) アクセス制御公開ヘッダー

このフィールドはオプションです。 CORS リクエストを行う場合、

オブジェクトの XMLHttpRequest メソッドは、getResponseHeader()Cache-ControlContent-LanguageContent-TypeExpiresLast-Modified の 6 つの基本フィールドのみを取得できます。他のフィールドを取得したい場合は、Pragma で指定する必要があります。上の例では、Access-Control-Expose-HeadersgetResponseHeader('FooBar') フィールドの値を返すことができることを指定しています。 FooBar

3.2 withCredentials 属性

上で述べたように、CORS リクエストはデフォルトでは Cookie と HTTP 認証情報を送信しません。サーバーに Cookie を送信する場合は、サーバーの同意が必要で、

フィールドを指定します。 Access-Control-Allow-Credentials

<code>Access-Control-Allow-Credentials: true</code>

一方、開発者は AJAX リクエストの

属性をオンにする必要があります。 withCredentials

<code>var xhr = new XMLHttpRequest();xhr.withCredentials = true;</code>

否则,即使服务器同意发送Cookie,浏览器也不会发送。或者,服务器要求设置Cookie,浏览器也不会处理。

但是,如果省略withCredentials设置,有的浏览器还是会一起发送Cookie。这时,可以显式关闭withCredentials

<code>xhr.withCredentials = false;</code>

需要注意的是,如果要发送Cookie,Access-Control-Allow-Origin就不能设为星号,必须指定明确的、与请求网页一致的域名。同时,Cookie依然遵循同源政策,只有用服务器域名设置的Cookie才会上传,其他域名的Cookie并不会上传,且(跨源)原网页代码中的document.cookie也无法读取服务器域名下的Cookie。

四、非简单请求4.1 预检请求

非简单请求是那种对服务器有特殊要求的请求,比如请求方法是PUTDELETE,或者Content-Type字段的类型是application/json

非简单请求的CORS请求,会在正式通信之前,增加一次HTTP查询请求,称为"预检"请求(preflight)。

浏览器先询问服务器,当前网页所在的域名是否在服务器的许可名单之中,以及可以使用哪些HTTP动词和头信息字段。只有得到肯定答复,浏览器才会发出正式的XMLHttpRequest请求,否则就报错。

下面是一段浏览器的JavaScript脚本。

var url = 'http://api.alice.com/cors';var xhr = new XMLHttpRequest();xhr.open('PUT', url, true);xhr.setRequestHeader('X-Custom-Header', 'value');xhr.send();

上面代码中,HTTP请求的方法是PUT,并且发送一个自定义头信息X-Custom-Header

浏览器发现,这是一个非简单请求,就自动发出一个"预检"请求,要求服务器确认可以这样请求。下面是这个"预检"请求的HTTP头信息。

<code>OPTIONS /cors HTTP/1.1Origin: http://api.bob.comAccess-Control-Request-Method: PUTAccess-Control-Request-Headers: X-Custom-HeaderHost: api.alice.comAccept-Language: en-USConnection: keep-aliveUser-Agent: Mozilla/5.0...</code>

"预检"请求用的请求方法是OPTIONS,表示这个请求是用来询问的。头信息里面,关键字段是Origin,表示请求来自哪个源。

除了Origin字段,"预检"请求的头信息包括两个特殊字段。

(1)Access-Control-Request-Method

该字段是必须的,用来列出浏览器的CORS请求会用到哪些HTTP方法,上例是PUT

(2)Access-Control-Request-Headers

该字段是一个逗号分隔的字符串,指定浏览器CORS请求会额外发送的头信息字段,上例是X-Custom-Header

4.2 预检请求的回应

服务器收到"预检"请求以后,检查了OriginAccess-Control-Request-MethodAccess-Control-Request-Headers字段以后,确认允许跨源请求,就可以做出回应。

HTTP/1.1 200 OKDate: Mon, 01 Dec 2008 01:15:39 GMTServer: Apache/2.0.61 (Unix)Access-Control-Allow-Origin: http://api.bob.comAccess-Control-Allow-Methods: GET, POST, PUTAccess-Control-Allow-Headers: X-Custom-HeaderContent-Type: text/html; charset=utf-8Content-Encoding: gzipContent-Length: 0Keep-Alive: timeout=2, max=100Connection: Keep-AliveContent-Type: text/plain

上面的HTTP回应中,关键的是Access-Control-Allow-Origin字段,表示<a href="http://api.bob.com">http://api.bob.com</a>可以请求数据。该字段也可以设为星号,表示同意任意跨源请求。

Access-Control-Allow-Origin: *

如果浏览器否定了"预检"请求,会返回一个正常的HTTP回应,但是没有任何CORS相关的头信息字段。这时,浏览器就会认定,服务器不同意预检请求,因此触发一个错误,被XMLHttpRequest对象的onerror回调函数捕获。控制台会打印出如下的报错信息。

XMLHttpRequest cannot load http://api.alice.com.Origin http://api.bob.com is not allowed by Access-Control-Allow-Origin.

服务器回应的其他CORS相关字段如下。

<code>Access-Control-Allow-Methods: GET, POST, PUTAccess-Control-Allow-Headers: X-Custom-HeaderAccess-Control-Allow-Credentials: trueAccess-Control-Max-Age: 1728000</code>

(1)Access-Control-Allow-Methods

该字段必需,它的值是逗号分隔的一个字符串,表明服务器支持的所有跨域请求的方法。注意,返回的是所有支持的方法,而不单是浏览器请求的那个方法。这是为了避免多次"预检"请求。

(2)Access-Control-Allow-Headers

如果浏览器请求包括Access-Control-Request-Headers字段,则Access-Control-Allow-Headers字段是必需的。它也是一个逗号分隔的字符串,表明服务器支持的所有头信息字段,不限于浏览器在"预检"中请求的字段。

(3)Access-Control-Allow-Credentials

该字段与简单请求时的含义相同。

(4)Access-Control-Max-Age

このフィールドはオプションであり、このプリフライトリクエストの有効期間を秒単位で指定するために使用されます。上記の結果では、有効期間は 20 日 (1728000 秒) です。これは、応答を 1728000 秒 (20 日間) キャッシュできることを意味します。この期間中は、別のプリフライト リクエストを発行する必要はありません。

4.3 ブラウザの通常のリクエストとレスポンス

サーバーが「プリフライト」リクエストを渡すと、ブラウザからの通常の CORS リクエストはすべて単純なリクエストと同じになり、Origin ヘッダー情報フィールドが存在します。サーバーの応答には Access-Control-Allow-Origin ヘッダー情報フィールドもあります。

以下は、「プリフライト」リクエスト後のブラウザの通常の CORS リクエストです。

PUT /cors HTTP/1.1Origin: http://api.bob.comHost: api.alice.comX-Custom-Header: valueAccept-Language: en-USConnection: keep-aliveUser-Agent: Mozilla/5.0...

上記のヘッダー情報の Origin フィールドは、ブラウザによって自動的に追加されます。

以下はサーバーからの通常の応答です。

Access-Control-Allow-Origin: http://api.bob.comContent-Type: text/html; charset=utf-8

上記のヘッダー情報では、Access-Control-Allow-Origin フィールドをすべての応答に含める必要があります。

5. JSONPとの比較

CORS は JSONP と同じ目的で使用されますが、JSONP よりも強力です。

JSONP は GET リクエストのみをサポートしますが、CORS はすべての種類の HTTP リクエストをサポートします。 JSONP の利点は、古いブラウザをサポートし、CORS をサポートしていない Web サイトからデータを要求できることです。

(終了)

声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
Python vs. JavaScript:開発者の比較分析Python vs. JavaScript:開発者の比較分析May 09, 2025 am 12:22 AM

PythonとJavaScriptの主な違いは、タイプシステムとアプリケーションシナリオです。 1。Pythonは、科学的コンピューティングとデータ分析に適した動的タイプを使用します。 2。JavaScriptは弱いタイプを採用し、フロントエンドとフルスタックの開発で広く使用されています。この2つは、非同期プログラミングとパフォーマンスの最適化に独自の利点があり、選択する際にプロジェクトの要件に従って決定する必要があります。

Python vs. JavaScript:ジョブに適したツールを選択するPython vs. JavaScript:ジョブに適したツールを選択するMay 08, 2025 am 12:10 AM

PythonまたはJavaScriptを選択するかどうかは、プロジェクトの種類によって異なります。1)データサイエンスおよび自動化タスクのPythonを選択します。 2)フロントエンドとフルスタック開発のためにJavaScriptを選択します。 Pythonは、データ処理と自動化における強力なライブラリに好まれていますが、JavaScriptはWebインタラクションとフルスタック開発の利点に不可欠です。

PythonとJavaScript:それぞれの強みを理解するPythonとJavaScript:それぞれの強みを理解するMay 06, 2025 am 12:15 AM

PythonとJavaScriptにはそれぞれ独自の利点があり、選択はプロジェクトのニーズと個人的な好みに依存します。 1. Pythonは、データサイエンスやバックエンド開発に適した簡潔な構文を備えた学習が簡単ですが、実行速度が遅くなっています。 2。JavaScriptはフロントエンド開発のいたるところにあり、強力な非同期プログラミング機能を備えています。 node.jsはフルスタックの開発に適していますが、構文は複雑でエラーが発生しやすい場合があります。

JavaScriptのコア:CまたはCの上に構築されていますか?JavaScriptのコア:CまたはCの上に構築されていますか?May 05, 2025 am 12:07 AM

javascriptisnotbuiltoncorc;それは、解釈されていることを解釈しました。

JavaScriptアプリケーション:フロントエンドからバックエンドまでJavaScriptアプリケーション:フロントエンドからバックエンドまでMay 04, 2025 am 12:12 AM

JavaScriptは、フロントエンドおよびバックエンド開発に使用できます。フロントエンドは、DOM操作を介してユーザーエクスペリエンスを強化し、バックエンドはnode.jsを介してサーバータスクを処理することを処理します。 1.フロントエンドの例:Webページテキストのコンテンツを変更します。 2。バックエンドの例:node.jsサーバーを作成します。

Python vs. Javascript:どの言語を学ぶべきですか?Python vs. Javascript:どの言語を学ぶべきですか?May 03, 2025 am 12:10 AM

PythonまたはJavaScriptの選択は、キャリア開発、学習曲線、エコシステムに基づいている必要があります。1)キャリア開発:Pythonはデータサイエンスとバックエンド開発に適していますが、JavaScriptはフロントエンドおよびフルスタック開発に適しています。 2)学習曲線:Python構文は簡潔で初心者に適しています。 JavaScriptの構文は柔軟です。 3)エコシステム:Pythonには豊富な科学コンピューティングライブラリがあり、JavaScriptには強力なフロントエンドフレームワークがあります。

JavaScriptフレームワーク:最新のWeb開発のパワーJavaScriptフレームワーク:最新のWeb開発のパワーMay 02, 2025 am 12:04 AM

JavaScriptフレームワークのパワーは、開発を簡素化し、ユーザーエクスペリエンスとアプリケーションのパフォーマンスを向上させることにあります。フレームワークを選択するときは、次のことを検討してください。1。プロジェクトのサイズと複雑さ、2。チームエクスペリエンス、3。エコシステムとコミュニティサポート。

JavaScript、C、およびブラウザの関係JavaScript、C、およびブラウザの関係May 01, 2025 am 12:06 AM

はじめに私はあなたがそれを奇妙に思うかもしれないことを知っています、JavaScript、C、およびブラウザは正確に何をしなければなりませんか?彼らは無関係であるように見えますが、実際、彼らは現代のウェブ開発において非常に重要な役割を果たしています。今日は、これら3つの間の密接なつながりについて説明します。この記事を通して、JavaScriptがブラウザでどのように実行されるか、ブラウザエンジンでのCの役割、およびそれらが協力してWebページのレンダリングと相互作用を駆動する方法を学びます。私たちは皆、JavaScriptとブラウザの関係を知っています。 JavaScriptは、フロントエンド開発のコア言語です。ブラウザで直接実行され、Webページが鮮明で興味深いものになります。なぜJavascrを疑問に思ったことがありますか

See all articles

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

Video Face Swap

Video Face Swap

完全無料の AI 顔交換ツールを使用して、あらゆるビデオの顔を簡単に交換できます。

ホットツール

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

AtomエディタMac版ダウンロード

AtomエディタMac版ダウンロード

最も人気のあるオープンソースエディター

mPDF

mPDF

mPDF は、UTF-8 でエンコードされた HTML から PDF ファイルを生成できる PHP ライブラリです。オリジナルの作者である Ian Back は、Web サイトから「オンザフライ」で PDF ファイルを出力し、さまざまな言語を処理するために mPDF を作成しました。 HTML2FPDF などのオリジナルのスクリプトよりも遅く、Unicode フォントを使用すると生成されるファイルが大きくなりますが、CSS スタイルなどをサポートし、多くの機能強化が施されています。 RTL (アラビア語とヘブライ語) や CJK (中国語、日本語、韓国語) を含むほぼすべての言語をサポートします。ネストされたブロックレベル要素 (P、DIV など) をサポートします。

Dreamweaver Mac版

Dreamweaver Mac版

ビジュアル Web 開発ツール

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境