プライベートな連絡先の最初の情報
送料メール:
2024-07-12
한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina
目次
2. クロスドメイントランザクションにはどのような制限がありますか?
4.2CORS は単純なクロスドメインリクエストを解決します
4.4CORS は複雑なクロスドメインリクエストを解決します
コードアドレス git clone https://gitee.com/childe-jia/cross-domain-test.git
同一生成元ポリシーは、リソースのセキュリティを確保するためにブラウザが従うポリシーです。このポリシーは、リソースへのアクセスにいくつかの制限を課します。
W3C の同一オリジン ポリシーの説明:同一生成元ポリシー。
1 ソースコンポーネント
2 以下の表では、最後の行の 2 つのソースのみが同じ起源を持っています。
ソース1 | ソース2 | 相同ですか? |
http://www.xyz.com/ホーム | https://www.xyz.com/home | ⛔非均質️ |
http://www.xyz.com/ホーム | http://mail.xyz.com/home | ⛔不均質 |
http://www.xyz.com:8080/home | http://www.xyz.com:8090/ホーム | ⛔不均質 |
http://www.xyz.com:8080/home | http://www.xyz.com:8080/検索 | ✅出身地が同じ︎ |
3 オリジンリクエスト
4 オリジナルでないリクエスト
5 要約: 「ソース」が「ターゲット ソース」と一致しない場合、それは「非ソース」を意味し、「ヘテロソース」または「クロスドメイン」とも呼ばれます。
たとえば、「ソース A」と「ソース B」という 2 つのソースがあり、それらが「同じオリジンではない」場合、ブラウザには次の制限があります。
「ソース A」のスクリプトは「ソース B」の DOM にアクセスできません。
- <!-- <iframe id="framePage" src="./demo.html"></iframe> -->
- <iframe id="framePage" src="https://www.baidu.com"></iframe>
-
- <script type="text/javascript" >
- function showDOM(){
- const framePage = document.getElementById('framePage')
- console.log(framePage.contentWindow.document) //同源的可以获取,非同源的无法获取
- }
- </script>
「ソース A」は「ソース B」の Cookie にアクセスできません
- <iframe id="baidu" src="http://www.baidu.com" width="500" height="300"></iframe>
-
- <script type="text/javascript" >
- // 访问的是当前源的cookie,并不是baidu的cookie
- console.log(document.cookie)
- </script>
「ソース A」は「ソース B」にリクエストを送信できますが、「ソース B」からの応答データを取得することはできません。
- const url = 'https://www.toutiao.com/hot-event/hot-board/?origin=toutiao_pc'
- let result = await fetch(url)
- let data = await result.json();
- console.log(data)
注: 上記の制限のうち、ブラウザによる Ajax データ取得の制限が最も影響が大きく、実際の開発では頻繁に遭遇します。
CORS の正式名: Cross-Origin Resource Sharing (Cross-Origin Resource Sharing) は、クロスドメイン要求のブラウザー検証を制御するために使用される一連の仕様です。サーバーは CORS 仕様に従い、ブラウザー検証を制御するための特定の応答ヘッダーを追加します。一般的なルールは次のとおりです。
●サーバーがクロスドメインリクエストを明示的に拒否するか、それを示さないため、ブラウザは検証に失敗します。
●サーバーはクロスドメイン要求が許可されていることを明確に示しており、ブラウザーの検証に合格します。
注: CORS を使用してクロスドメインの問題を解決するのは最もオーソドックスな方法であり、サーバーが「独自の」サーバーである必要があります。
全体的な考え方: サーバーが応答すると、Access-Control-Allow-Origin 応答ヘッダーを追加することで、特定のソースがクロスドメイン リクエストの開始を許可されていることを明確に表現し、ブラウザーは検証中にそれを直接渡します。
サーバー側のコア コード (Express フレームワークを例にします):
- // 处理跨域中间件
- function corsMiddleWare(req,res,next){
- // 允许 http://127.0.0.1:5500 这个源发起跨域请求
- // res.setHeader('Access-Control-Allow-Origin','http://127.0.0.1:5500')
-
- // 允许所有源发起跨域请求
- res.setHeader('Access-Control-Allow-Origin','*')
- next()
- }
-
- // 配置路由并使用中间件
- app.get('/',corsMiddleWare,(req,res)=>{
- res.send('hello!')
- })
CORS はリクエストを、①単純なリクエストと②複雑なリクエストの 2 つのカテゴリに分類します。
簡単なリクエスト | 複雑なリクエスト |
✅リクエストメソッド(メソッド)はGET、HEAD、POST | 1 は、単純なリクエストまたは複雑なリクエストのいずれかです。 |
✅リクエストヘッダーフィールドは以下に準拠する必要があります「CORSセキュリティ仕様」 | |
✅リクエストヘッダーのContent-Type値は以下の3つのみです。 |
プリフライトリクエストについて:
リクエストヘッダー | 意味 |
起源 | リクエストのソース |
アクセス制御リクエストメソッド | 実際にリクエストされたHTTPメソッド |
アクセス制御リクエストヘッダー | 実際のリクエストで使用されるカスタムヘッダー (存在する場合) |
1 ステップ 1: サーバーは最初にブラウザのプリフライト要求を渡し、次の応答ヘッダーを返す必要があります。
応答ヘッダー | 意味 |
アクセス制御許可オリジン | 許可されたソース |
アクセス制御許可メソッド | 許可されたメソッド |
アクセス制御許可ヘッダー | 許可されるカスタムヘッダー |
アクセス制御の最大有効期間 | プリフライトリクエストの結果キャッシュ時間 (オプション) |
2 ステップ 2: 実際のクロスドメイン リクエストを処理する (単純なクロスドメイン リクエストを処理するのと同じ方法)
サーバーコアコード:
- // 处理预检请求
- app.options('/students', (req, res) => {
- // 设置允许的跨域请求源
- res.setHeader('Access-Control-Allow-Origin', 'http://127.0.0.1:5500')
- // 设置允许的请求方法
- res.setHeader('Access-Control-Allow-Methods', 'GET')
- // 设置允许的请求头
- res.setHeader('Access-Control-Allow-Headers', 'school')
- // 设置预检请求的缓存时间(可选)
- res.setHeader('Access-Control-Max-Age', 7200)
- // 发送响应
- res.send()
- })
-
- // 处理实际请求
- app.get('/students', (req, res) => {
- // 设置允许的跨域请求源
- res.setHeader('Access-Control-Allow-Origin', 'http://127.0.0.1:5500')
- // 随便设置一个自定义响应头
- res.setHeader('abc',123)
- // 设置允许暴露给客户端的响应头
- res.setHeader('Access-Control-Expose-Headers', 'abc')
- // 打印请求日志
- console.log('有人请求/students了')
- // 发送响应数据
- res.send(students)
- })
上記の構成では、応答ヘッダーを自分で構成するか、または cors ライブラリを使用してミドルウェアを手動でカプセル化する必要があります。より簡単に構成を完了できます。
●corsのインストール
npm i cors
●シンプルな構成コルス
app.use(cors())
●corsを完全に設定する
- // cors中间件配置
- const corsOptions = {
- origin: 'http://127.0.0.1:5500', // 允许的源
- methods: ['GET', 'POST', 'PUT', 'DELETE', 'HEAD', 'OPTIONS'], // 允许的方法
- allowedHeaders: ['school'], // 允许的自定义头
- exposedHeaders: ['abc'], // 要暴露的响应头
- optionsSuccessStatus: 200 // 预检请求成功的状态码
- };
-
- app.use(cors(corsOptions)); // 使用cors中间件
デフォルトでは、js はバックエンドによって設定された応答ヘッダーにアクセスできないため、バックエンドによって公開される必要があります。
1JSONP の概要: JSONP の使用法<script>标签可以跨域加载脚本,且不受严格限制的特性,可以说是程序员智慧的结晶,早期一些浏览器不支持 CORS 的时,可以靠 JSONP 解决跨域。
2基本的なプロセス:
3イラスト:
4 つのコード例:
- <button onclick="getTeachers()">获取数据</button>
-
- <script type="text/javascript" >
- function callback(data){
- console.log(data)
- }
-
- function getTeachers(url){
- // 创建script元素
- const script = document.createElement('script')
- // 指定script的src属性
- script.src= 'http://127.0.0.1:8081/teachers'
- // 将script元素添加到body中触发脚本加载
- document.body.appendChild(script)
- // script标签加载完毕后移除该标签
- script.onload = ()=>{
- script.remove()
- }
- }
- </script>
5jQueryでカプセル化されたjsonp
?callback=?' は固定形式であり、自動的に解析されます。
- $.getJSON('http://127.0.0.1:8081/teachers?callback=?',(data)=>{
- console.log(data)
- })
サーバー間でクロスドメインの問題は発生しません。サーバーとページが同じオリジンの下にあることを確認するには、express を使用して静的リソースを開始する必要があります。
- // 启动静态资源 让服务器跟页面同一个源
- app.use(express.static("./public"));
http-proxy-middleware を使用してプロキシを構成する
- const { createProxyMiddleware } = require('http-proxy-middleware');
-
- app.use('/api',createProxyMiddleware({
- target:'https://www.toutiao.com',
- changeOrigin:true,
- pathRewrite:{
- '^/api':''
- }
アドバンテージ:
欠点:
使用するシーン:
全体的なアイデアは、nginx に静的コンテンツ サーバーとプロキシ サーバーの両方の 2 つの役割を果たさせることです。
nginx の設定を次のように変更します。nginx のルート ディレクトリは C ドライブではないことが望ましいことに注意してください。
- # 配置nginx根目录
- location / {
- root D:dist;
- index index.html index.htm;
- }
-
- # 配置代理
- location /dev/ {
- # 设置代理目标
- proxy_pass http://sph-h5-api.atguigu.cn/;
- }
2 フロントエンド プロジェクトを変更して、すべてのリクエストが /dev に転送されてから再パッケージ化されるようにします。
- const request = axios.create({
- baseURL:'/dev',
- timeout:10000
- })
次に、nginx サーバーに直接アクセスします。たとえば、nginx がポート 8099 で実行されている場合は、アクセスします。
http://localhost:8099
次に、リフレッシュ 404 問題が発生します。これを解決するには、nginx 構成を追加します。
-
- # 配置nginx根目录
- location / {
- root D:dist;
- index index.html index.htm;
- try_files $uri $uri/ /index.html; # 解决刷新404
- }
- # 配置代理
- location /dev/ {
- # 设置代理目标
- proxy_pass http://sph-h5-api.atguigu.cn/;
- }
これら 2 つの「/」を追加すると、dev が削除されます
1. vue.config.js ファイルを使用してプロキシを構成します。
Vue プロジェクトのルート ディレクトリに vue.config.js ファイルを作成し、次のコードを追加します。
- module.exports = {
- devServer: {
- proxy: {
- '/api': {
- target: 'http://api.example.com',
- changeOrigin: true,
- pathRewrite: {
- '^/api': ''
- }
- }
- }
- }
- }
上記のコードでは、devServer
プロキシサーバーを設定するための設定項目です。でproxy
プロパティはプロキシのルールを構成するために使用されます。/api
プロキシが必要なインターフェイス パスを示します。target
この属性はプロキシのターゲット サーバー アドレスを表します。changeOrigin
この属性は、リクエストの送信元アドレスを変更するかどうかを示します。pathRewrite
要求されたパスをオーバーライドするために使用されるプロパティ。
アドバンテージ:
欠点:
使用するシーン: