ホームページ >ウェブフロントエンド >jsチュートリアル >CORS クロスドメイン リソース共有の詳細な紹介 (コード付き)

CORS クロスドメイン リソース共有の詳細な紹介 (コード付き)

不言
不言転載
2019-03-12 16:55:312138ブラウズ

この記事では、CORS クロスドメイン リソース共有 (コード付き) について詳しく説明します。これには一定の参考価値があります。必要な友人は参照できます。お役に立てば幸いです。

同一オリジンポリシーを理解する

ソース (オリジン)*: プロトコル、ドメイン名、ポート番号です; 同一オリジン: 同じソース、つまりプロトコルを意味します、ドメイン名とポートはまったく同じです; 同一オリジン ポリシー : 同一オリジン ポリシーは、ブラウザのセキュリティ機能です。異なるオリジンのクライアント スクリプトは、明示的な承認なしに相互にリソースを読み書きすることはできません。同一オリジン ポリシーの分類:

DOM 同一オリジン ポリシー: DOM の場合、異なるソース ページの DOM を操作することは禁止されています。たとえば、異なるドメイン名の iframe は相互アクセスを制限します。 XMLHttpRequest オリジン ポリシー: XHR オブジェクトを使用して、異なるオリジンを持つサーバー アドレスへの HTTP リクエストを開始することは禁止されています。

は同一生成元ポリシーによって制限されません:

ページ内のリンク、リダイレクト、およびフォーム送信 (フォーム送信およびアクション ドメインへのデータ送信後は、ページ自体には何も行われないため)リクエストの結果は気にせず、後続のすべての操作はアクション内のドメインに渡され、同一生成元ポリシーによって制限されません。リソースの導入は制限されていませんが、js はロードされたコンテンツ (ページに埋め込まれている CORS クロスドメイン リソース共有の詳細な紹介 (コード付き) など) を読み書きすることはできません。 、

なぜクロスドメイン制限があるのか​​

DOM 同一オリジンポリシーがない場合: あなたの Web サイトはあなたの Web サイトではないため、xss に関する調査は行われません。ただし、Web サイトのインターフェイスを操作するコードは誰でも作成できます。

XMLHttpRequest オリジン ポリシーがない場合、CSRF (クロスサイト リクエスト フォージェリ) 攻撃が簡単に実行できます。

ユーザー 自分の Web サイト ページ a.com にログインすると、ユーザー ID が Cookie に追加されます。ユーザーは悪意のあるページ b.com を閲覧し、ページ内の悪意のある AJAX リクエスト コードを実行しました。 b.com は a.com への AJAX HTTP リクエストを開始し、このリクエストはデフォルトで a.com に対応する Cookie も送信します。 a.com は、送信された Cookie からユーザー ID を抽出し、ユーザーが正しいことを確認し、要求データを応答で返しますが、データが漏洩します。また、Ajax はバックグラウンドで実行されるため、このプロセスはユーザーには見えません。 (添付) XMLHttpRequest では、同一生成元ポリシーで CSRF 攻撃を制限できますか?同一オリジン ポリシーの対象外となるものもあることを忘れないでください。フォームの送信やリソースの導入 (セキュリティの問題については次号で検討します)

#クロスドメイン ソリューション

JSONP クロスドメイン: スクリプト タグから借用 ブラウザの同一オリジン ポリシーの影響を受けず、リソースのクロスドメイン参照が許可されるため、スクリプト タグを動的に作成し、src 属性をクロス タグに使用できます。 -domain;

欠点: すべての Web サイトがデータを取得できるため、セキュリティが確保されます。性的な問題では、Web サイトの両側で基本トークンの ID 検証をネゴシエートする必要があります。 GET のみ可能であり、POST はできません。悪意のあるコードが挿入され、ページのコンテンツが改ざんされる可能性があります。この問題を回避するには、文字列フィルタリングを使用できます。サーバー プロキシ: ブラウザーにはクロスドメインの制限がありますが、サーバーにはクロスドメインの問題がないため、サーバーは目的のドメイン内のリソースを要求して、それらをクライアントに返すことができます。 document.domain、window.name、location.hash: iframe を使用して DOM 同一オリジン ポリシーを解決する postMessage: DOM 同一オリジン ポリシーを解決する、新しいソリューション CORS (クロスドメイン リソース共有): ここでの重要なポイント

CORS (クロスドメイン リソース共有)

HTML5 によって提供される標準のクロスドメイン ソリューションは、ブラウザーが従い、HTTP ヘッダーを通じて対話する一連の制御戦略であり、CORS は主にバックエンドを通じて設定されます。設定項目。

CORS は使い方が簡単です

前述したように、CORS はクロスドメインです。バックエンドで Access-Control-Allow-Origin を設定するだけです: *|[または特定のドメイン名] ; 最初の試行:

app.use(async(ctx,next) => {
    ctx.set({
        "Access-Control-Allow-Origin": "http://localhost:8088"
})
一部のリクエストは成功する可能性がありますが、依然としてエラーを報告するリクエストもあります:

リクエストは同一生成元ポリシーによってブロックされており、プレ-request 応答がチェックに合格しません: http 応答が正常ではありません?

CORS クロスドメイン リソース共有の詳細な紹介 (コード付き)

と、OPTIONS リクエストが送信されたことがわかります:

#CORS 仕様では、リクエストが 2 つのタイプに分類されていることがわかりました。1 つは単純なリクエストで、もう 1 つはプリフライト付きの非単純なリクエストです。CORS クロスドメイン リソース共有の詳細な紹介 (コード付き)

単純なリクエストと非単純なリクエスト

クロスドメイン リクエストの送信時にブラウザが判断する方法:

ブラウザがクロスドメイン リクエストを送信すると、まずそれが単純なリクエストであるか、単純でないリクエストであるかを判断します。これは単純なリクエストであり、最初にサーバー プログラムが実行され、次にブラウザがクロスドメインかどうかを判断します。また、単純でないリクエストの場合、ブラウザは実際のリクエストを送信する前に OPTIONS HTTP リクエストを送信して判断します。サーバーがクロスドメインリクエストを受け入れることができるかどうか、受け入れられない場合、ブラウザはその後の実際のリクエストの発生を直接阻止します。単純なリクエストとは何ですか?

リクエスト メソッドは次のいずれかです:

GETHEADPOST

すべてのヘッダーには次のリストのみが含まれます (カスタム ヘッダーは含まれません):

Cache-ControlContent-LanguageContent-TypeExpiresLast-ModifiedPragma除此之外都是非简单请求

CORS非简单请求配置须知

正如上图报错显示,对于非简单请求,浏览器会先发送options预检,预检通过后才会发送真是的请求;发送options预检请求将关于接下来的真实请求的信息给服务器:

Origin:请求的源域信息
Access-Control-Request-Method:接下来的请求类型,如POST、GET等
Access-Control-Request-Headers:接下来的请求中包含的用户显式设置的Header列表
服务器端收到请求之后,会根据附带的信息来判断是否允许该跨域请求,通过Header返回信息:
Access-Control-Allow-Origin:允许跨域的Origin列表
Access-Control-Allow-Methods:允许跨域的方法列表
Access-Control-Allow-Headers:允许跨域的Header列表,防止遗漏Header,因此建议没有特殊需求的情况下设置为*
Access-Control-Expose-Headers:允许暴露给JavaScript代码的Header列表
Access-Control-Max-Age:最大的浏览器预检请求缓存时间,单位为s

CORS完整配置

koa配置CORS跨域资源共享中间件:
const cors = (origin) => {
    return async (ctx, next) => {
        ctx.set({
            "Access-Control-Allow-Origin": origin, //允许的源
        })
        // 预检请求
        if (ctx.request.method == "OPTIONS") {
            ctx.set({
                'Access-Control-Allow-Methods': 'OPTIONS,HEAD,DELETE,GET,PUT,POST', //支持跨域的方法
                'Access-Control-Allow-Headers': '*', //允许的头
                'Access-Control-Max-Age':10000, // 预检请求缓存时间
                // 如果服务器设置Access-Control-Allow-Credentials为true,那么就不能再设置Access-Control-Allow-Origin为*,必须用具体的域名
                'Access-Control-Allow-Credentials':true // 跨域请求携带身份信息(Credential,例如Cookie或者HTTP认证信息)
            });
            ctx.send(null, '预检请求')
        } else {
            // 真实请求
            await next()
        }
    }
}

export default cors

现在不管是简单请求还是非简单请求都可以跨域访问啦~

跨域时如何处理cookie

cookie:

我们知道http时无状态的,所以在维持用户状态时,我们一般会使用cookie;cookie每次同源请求都会携带;但是跨域时cookie是不会进行携带发送的;

问题:

由于cookie对于不同源是不能进行操作的;这就导致,服务器无法进行cookie设置,浏览器也没法携带给服务器(场景:用户登录进行登录操作后,发现响应中有set-cookie但是,浏览器cookie并没有相应的cookie)

决解:

浏览器请求设置withCredentials为true即可让该跨域请求携带 Cookie;使用axios配置axios.defaults.withCredentials = true服务器设置Access-Control-Allow-Credentials=true允许跨域请求携带 Cookie“积跬步、行千里”—— 持续更新中~,喜欢的话留下个赞和关注哦!

往期经典好文:

服务器(CentOS)安装配置mongodbKoa日志中间件封装开发(log4js)团队合作必备的Git操作使用pm2部署node生产环境

以上がCORS クロスドメイン リソース共有の詳細な紹介 (コード付き)の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はsegmentfault.comで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。