いくつかの一般的なnodejsドメイン間ソリューション
29762 ワード
ajaxを使用して前後のデータインタラクションを行う場合、ドメイン間でエラーメッセージが表示されることがよくあります.
ドメイン間で生成される理由
これは、ブラウザの同源ポリシーのためです.これはブラウザの最も核心的で最も基本的なセキュリティ機能であり、あるドメインにロードされたスクリプトが別のドメインのドキュメント属性を取得または操作することを阻止します.(つまり,要求されたURLのドメインは現在のウェブページのドメインと同じでなければならない),同源ポリシーが欠けているとブラウザはXSS,CSFRなどの攻撃を受けやすい.
ドメイン間で発生する状況はどれですか?ポートが異なる プロトコルが異なる ドメイン名が異なる 同じURLとドメイン名に対応するIPが異なる//localhostと127.0.0.1はドメイン間 を生成します.
まとめ:ポートが異なり、ドメイン名が異なり、プロトコルが異なるとドメイン間で表示されます.
同源ポリシーは、次の動作を制限します. Cookie、LocalStorage、IndexDBは を読めません. DOMとJSオブジェクトは を取得できません. AJAXリクエストは 送信できません.
ドメイン間での解決方法
フロントエンド開発では、ドメイン間で問題が発生することは避けられません.以下、4つの方法を参照してください.
注意:ドメイン間で一般的に発生するのは、前後の共通構成の解決である必要があります.
方法1:サーバエージェント
基本原理:サーバ間のリクエストにドメイン間の問題はありません.まずフロントエンドが自分のサーバを要求する.サードパーティ製ミドルウェアcorsにより、フロントエンドと自分のサーバ間のドメイン間の問題を解決します. 当方のサーバは、ターゲットサーバに対するサーバ要求の送信を開始します. は、ネットワーク要求の結果をフロントエンド に返す.
フロントエンドコード:
server.js:
方法2:JSONP方式(フロントエンド常用)
コア:scriptラベルのsrcプロパティにはドメイン間は存在せず、ファイル情報をロードできます.
一般的にサードパーティインタフェースでは、サーバとクライアント間の通信の一般的な方法として使用できます.全プラットフォームブラウザでサポートされています.
例えば、タオバオでお勧めのデータインタフェースに戻る必要があります.
scriptラベルでドメイン間リクエストを実装し、jsonデータでコールバック関数を実行できます.
このインタフェースで印刷されたデータは、下図に示すのように、プロジェクトがvueで書かれている場合は、jsonpというモジュールも使用できます.
api.js
index.vue
この方法は簡単ですが、弊害もあります. jsonpリクエスト方式はgetのみです.データを転送する過程で安全性がなく、転送できるデータの長さもかなり限られている. インタフェースはjsonpフォーマットに合致する必要があります.そうしないと、この方法では意味がありません.
方法3:cors設定要求の対応するヘッダフィールド
CORSはW 3 C規格で、「ドメイン間リソース共有」(Cross-origin resource sharing)と呼ばれています.これにより、ブラウザがソース間サーバにXMLhttpRequest要求を発行することができ、AJAXがソースとしか使用できない制限を克服します.
すべてのタイプのHTTPリクエストをサポートするが、ブラウザIE 10以下ではサポートされていない)、ajaxの各種ドメイン間リクエストに適している.
バックエンドコード:
postmanによるテスト結果を下図のように示します:
方法四:WebSocket(H 5新機能)
WebSocketはHTML 5の新しい通信プロトコルです.ブラウザとサーバのフルデュプレクス通信を実現し、ドメイン間通信を許可するserver push技術の良い実現です.
オリジナルwebsocketには互換性の問題があり、簡単に使えますが、低バージョンのブラウザでは使えません.サードパーティ製ライブラリを使用できます.socket.ioは互換性の問題をよく解決し、使用方法も少し複雑です.
フロントエンドコード:
server.js:
方法5:vue-cliのdevServerエージェント構成
フロントエンドアプリケーションとバックエンドAPIサーバが同じホスト上で実行されていない場合は、開発環境でAPIリクエストをAPIサーバにエージェントする必要があります.この問題は、vue.config.jsのdevServer.proxyオプションで構成できます.vue cli: devServer.proxyプロジェクトルートディレクトリの下にvue.config.jsファイル を新規作成 module.exports内にdevServerを設定してエージェント を処理するインタフェースを取得するネットワーク要求は、以前に設定した変更されたインタフェースの小さな暗号を使用して、ローカルサーバに要求を送信します.このときローカルサーバが受信アドレスは、/hehe/music/api/123であるため、ドメイン間 は生成されない.その後ローカルサーバを介してターゲットサーバに転送する、転送前にローカルサーバはtargetターゲットアドレス: に追加する.このとき、送信する準備ができているアドレスと元のアドレスが一致していないことに気づき、hehe識別子が1つ増えました. 削除する必要があります
シーンの操作
devServerによって設定されたエージェントは、ローカル環境でのみ使用できます.すなわち、エージェントによってリクエストがターゲットサーバに送信され、オンラインにパブリッシュされると、404パスが見つからないことを示すメッセージが表示されます.
小結
また、nginxエージェントのドメイン間、postMessageドメイン間、document.domain+iframe、location.hash+iframe、window.name+iframeなど、ドメイン間ソリューションもあります.
最適ではありません.最適なのは、プロジェクトの実際のシーンと組み合わせて適切なドメイン間スキームを選択することだけです.
Access to XMLHttpRequest at 'http://localhost:3000/cors' from origin 'null' has
been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on
the requested resource.
ドメイン間で生成される理由
これは、ブラウザの同源ポリシーのためです.これはブラウザの最も核心的で最も基本的なセキュリティ機能であり、あるドメインにロードされたスクリプトが別のドメインのドキュメント属性を取得または操作することを阻止します.(つまり,要求されたURLのドメインは現在のウェブページのドメインと同じでなければならない),同源ポリシーが欠けているとブラウザはXSS,CSFRなどの攻撃を受けやすい.
ドメイン間で発生する状況はどれですか?
まとめ:ポートが異なり、ドメイン名が異なり、プロトコルが異なるとドメイン間で表示されます.
同源ポリシーは、次の動作を制限します.
ドメイン間での解決方法
フロントエンド開発では、ドメイン間で問題が発生することは避けられません.以下、4つの方法を参照してください.
注意:ドメイン間で一般的に発生するのは、前後の共通構成の解決である必要があります.
方法1:サーバエージェント
基本原理:サーバ間のリクエストにドメイン間の問題はありません.
フロントエンドコード:
let url ='http://localhost:3000/cors';//
$.get(url,(data)=>{
console.log(data);//
})
server.js:
const cors = require('cors')
const axios =require('axios')
const express = require('express')
const path = require('path')
const app = express()
// cors
app.use(cors())// ,
app.get('/cors',(req,res)=>{
console.log(' ')
let url ='http://ustbhuangyi.com/music/api/getDiscList?g_tk=1928093487&inCharset=utf-8&outCharset=utf-8¬ice=0&format=json&platform=yqq&hostUin=0&sin=0&ein=29&sortId=5&needNewCode=0&categoryId=10000000&rnd=0.2209329929181545'
//
axios.get(url)
.then((data)=>{
// console.log(data.data)
res.send(data.data)
})
})
app.listen(3000,()=>{
console.log(' ')
})
方法2:JSONP方式(フロントエンド常用)
コア:scriptラベルのsrcプロパティにはドメイン間は存在せず、ファイル情報をロードできます.
一般的にサードパーティインタフェースでは、サーバとクライアント間の通信の一般的な方法として使用できます.全プラットフォームブラウザでサポートされています.
例えば、タオバオでお勧めのデータインタフェースに戻る必要があります.
let url = https://suggest.taobao.com
/sug?code=utf-8&q=%E8%A1%A3%E6%9C%8D&_ksTS=1577354356112_350
&callback=taobao&k=1&area=c2c&bucketid=3// , callback=
scriptラベルでドメイン間リクエストを実装し、jsonデータでコールバック関数を実行できます.
<script>
function taobao(data){
console.log(data);
}
</script>
このインタフェースで印刷されたデータは、下図に示すのように、プロジェクトがvueで書かれている場合は、jsonpというモジュールも使用できます.
api.js
import jsonp from 'jsonp'
const getData = () => {
let url = 'https://suggest.taobao.com/sug?code=utf-8&q=%E8%A1%A3%E6%9C%8D&_ksTS=1577354356112_350'
// param
return new Promise((resolve, reject) => {
jsonp(url,{param:'callback'},(err, data) => {
if(err){
reject(err)
}else {
resolve(data)
}
})
})
}
index.vue
import { getData} from "api/api.js";
getData().then((res)=>{
console.log(res) // ,
})
この方法は簡単ですが、弊害もあります.
方法3:cors設定要求の対応するヘッダフィールド
CORSはW 3 C規格で、「ドメイン間リソース共有」(Cross-origin resource sharing)と呼ばれています.これにより、ブラウザがソース間サーバにXMLhttpRequest要求を発行することができ、AJAXがソースとしか使用できない制限を克服します.
すべてのタイプのHTTPリクエストをサポートするが、ブラウザIE 10以下ではサポートされていない)、ajaxの各種ドメイン間リクエストに適している.
バックエンドコード:
var express = require('express');
var app = express();
//
function middleware(req, res, next) {
console.log(' ')
//
res.header("Access-Control-Allow-Origin", "*");// ,*
res.header("Access-Control-Allow-Headers", "X-Requested-With");// header
res.header("Access-Control-Allow-Methods", "PUT,POST,GET,DELETE,OPTIONS");//
res.header("X-Powered-By", ' 3.2.1');
res.header("Content-Type", "application/json;charset=utf-8");
next(); //
}
//all
app.all(middleware) // ,
app.get('/test', function (req, res) {
res.send(req.query);
})
app.listen(3000, function () {
console.log(' ');
})
postmanによるテスト結果を下図のように示します:
方法四:WebSocket(H 5新機能)
WebSocketはHTML 5の新しい通信プロトコルです.ブラウザとサーバのフルデュプレクス通信を実現し、ドメイン間通信を許可するserver push技術の良い実現です.
オリジナルwebsocketには互換性の問題があり、簡単に使えますが、低バージョンのブラウザでは使えません.サードパーティ製ライブラリを使用できます.socket.ioは互換性の問題をよく解決し、使用方法も少し複雑です.
フロントエンドコード:
<body>
<input type="text" id='msg' ><button onclick="send()">send</button>
<script>
//
var socket = io.connect('http://127.0.0.1:8081');
// hehe
socket.on('hehe',(data)=>{
console.log(' ',data)
})
function send(){
let msg = document.getElementById('msg').value
// xixi input value
socket.emit('xixi',msg)
}
</script>
</body>
server.js:
var express = require('express')
var app = express()
// socket express
var server = require('http').Server(app);
var io = require('socket.io')(server);
io.on('connection',(client)=>{
console.log(' ')
// hehe 123
client.emit('hehe',123)
// xixi
client.on('xixi',(data)=>{
console.log(' ',data)
})
})
server.listen(8081,()=>{
console.log(' ')
});
方法5:vue-cliのdevServerエージェント構成
フロントエンドアプリケーションとバックエンドAPIサーバが同じホスト上で実行されていない場合は、開発環境でAPIリクエストをAPIサーバにエージェントする必要があります.この問題は、vue.config.jsのdevServer.proxyオプションで構成できます.vue cli: devServer.proxy
module.exports={
devServer:{
proxy:{ //
//
'/hehe':{
target:'http://www.target.com', //
changeOrigin:true,
pathRewrite:{
"^/hehe":'' //
}
}
}
}
}
import axios from '../utils/axios'
let url ='/hehe/music/api/123'
axios.get(url)
target:'http://www.target.com'
を受信アドレスurl前:url ='http://www.target.com/hehe/music/api/123'
pathRewrite
が/heheをアドレスからシーンの操作
devServerによって設定されたエージェントは、ローカル環境でのみ使用できます.すなわち、エージェントによってリクエストがターゲットサーバに送信され、オンラインにパブリッシュされると、404パスが見つからないことを示すメッセージが表示されます.
小結
また、nginxエージェントのドメイン間、postMessageドメイン間、document.domain+iframe、location.hash+iframe、window.name+iframeなど、ドメイン間ソリューションもあります.
最適ではありません.最適なのは、プロジェクトの実際のシーンと組み合わせて適切なドメイン間スキームを選択することだけです.