記事のディレクトリ
同一生成元ポリシー
相同性のコンセプトは:2つのページが同じプロトコル、ドメイン名とポートを持っている場合は、2つのページがある限り異なるがあると、同じソースに属し、異なるソースです。
http://www.example.com/dir/page.html比較(私はデフォルトのポート80のポートの名前を書いていない)のための
http://www.example.com/dir/other.html(同種)
HTTP:/ /example.com/dir/other.html(異なるソース、異なるドメイン名)
http://www.example.com:81/dir/page.html(異なるソース、異なるポート番号)
HTTPS://www.example。 COM / DIR / page.html(異なるソース、異なるプロトコル)
元ポリシー
同一生成元ポリシーブラウザ、いくつかのプロパティを読み取りまたは設定するために、異なるソース、現在の「文書」から「文書」またはスクリプトを制限します。スクリプトは、あるドメインから別のドメインにロードされたドキュメントのプロパティにアクセスすることを許可されていません。
Ajaxリクエストの制限
アヤックスは、あなたのサーバに要求を送信することができます。サーバが非相同を送信する場合には、要求を拒否します。
ソリューション
相同な制限を使用して問題を解決するためにJSONP
1.サーバーは、異なる送信元アドレスは、スクリプトタグの属性に書かれている要求します
<script src="www.example.com"></script>
<script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.min.js"></script>
2.サーバーの応答データは、関数呼び出しのパラメータとしてクライアントのニーズに送るために、実際のデータの関数を呼び出すする必要があります。(jsのコードが実行されるデータは、標準のスクリプトタグと一緒に戻って戻ってきます)
const data = 'fn({name:'张三',age:'20'})';
//一到客户端页面就将在客户端页面中找到名为fn的函数并执行
res.send(data);
クライアント3.は(そうでない場合は、fn機能やエラーを見つけることができませんので、スクリプトタグの前に関数を定義してください)グローバルスコープの関数fnを定義します
function fn (data) { /*处理服务器端返回的数据的代码*/}
関数内のサーバから返さ4.プロセスデータ
function fn (data) { console.log(data);}
原理:JSONP(パディングとJSON)、Ajaxリクエストがデータ要求バックコンテンツが配置された後、それは、scriptタグのsrc属性、ドメイン間のjsスクリプトのsrc読み込み、戻り値jsのコードを使用することで、属していませんスクリプトが実行するJavaScriptコードとしてタグ付けします。これは完全に同一生成元ポリシーを回避します。
パッケージJSONPコード
考慮すべきはである:
1.動的送信要求(動的に作成するためのスクリプト)
2は、高再利用することができる
関数fn溶液として結ば3 JSONP、事前に定義されていない、呼び出し側によって送信された
クライアントに4変更はのコードの後端部で定義された機能には影響しません
、クライアントのコードを次のとおりです。
function jsonp (options) {
//解决每一次发送请求的回调函数名不能一样的问题,否则会发生覆盖
var funName = 'myfunction' +
Math.random().toString().replace('.','');
//将调用者传过来的success挂载到全局作用域上
Window[funName] = options.success;
var param = '';
//拼接请求参数
for (let key in options.data) {
param += '&' + key + '=' + options.data[key];
}
options.url = '?' + 'callback=' + funName + param;
//创建script标签
var script = document.createElement('script');
script.src = options.url;
//将script标签追加到页面中
document.body.appendChild(script);
script.onload = function () {
/*等到数据被加载完成后就删除script标签,
因为不删除的话有发送多次请求就会有多个script标签在body中,这是没有用处的
*/
document.body.removeChild(script);
}
}
var btn2 = document.getElementById('btn2');
//为按钮注册点击事件
btn2.onclick = function () {
jsonp({
url: 'http://www.baidu.com',
data:{
name:'lisi',
age:34
},
success:function (data){
console.log("success2")
}
})
}
サーバー側のコード
import path from 'path';
import express from 'express'
//使用express框架创建web服务
const app = express();
//设置静态资源访问服务器功能,
//设置了之后,public目录下的文件可以直接用url访问
app.use(express.static(path.join(__dirname,'public')));
//设置路由
app.get('/',(req,res) =>{
const fnName = req.query.callback;
const data = JSON.stringify({name:'zhangsan',sex:'man'})
const result = fnName + '(' + data + ')'
setTimeout(() => {
res.send(result)
}, 1000);
})
app.listen(3001);//监听端口
サーバコードの最適化:
import path from 'path';
//使用express框架创建web服务
const app = express();
//设置静态资源访问服务器功能,
//设置了之后,public目录下的文件可以直接用url访问
app.use(express.static(path.join(__dirname,'public')));
//设置路由
app.get('/',(req,res) =>{
res.jsonp({name:'zhangsan',age:34})//实际上是做了上面一样的操作
})
app.listen(3001);//监听端口
サーバー側のソリューション
原理:同一生成元ポリシーの制限のみクライアント、リソースへのサーバー・サイドのクロスドメインアクセス、我々は、サーバー側のリソースにアクセスするモジュールクロスドメインリクエストで、クライアントでいつものようにAjaxリクエストを送信し、クライアントにリソースを返すことができるように。
クライアントコード:
ajax({
type:'get',
url:'http://localhost:3000/server',
data:{name:'zhangsan',age:23},
header:{
'Content-type':'application/json'
},
sucess:function (data,object) {console.log('success!');
},
error:function (data,object) {console.log('error!');
}
})
サーバー側のコード:
import path from 'path';
import express from 'express'
import request from 'request'
//使用express框架创建web服务
const app = express();
//设置静态资源访问服务器功能,
//设置了之后,public目录下的文件可以直接用url访问
app.use(express.static(path.join(__dirname,'public')));
//设置路由
app.get('/',(req,res) =>{
request('http://localhost:3001/server',(error,response,body){
res.send(body);
})
})
app.listen(3000);//监听端口
CORSクロスオリジンリソースの共有
CORS:ブラウザがサーバーにクロスドメインAjaxリクエストを送信することができます完全な名前のクロスオリジンリソース共有、アヤックスは、相同の使用の制限を克服します。
原則:実際には、クライアントはブラウザにリクエストを送信し、それは要求の先頭に起源(ソース)が表示されますが、同種またはクロスドメインリクエストリソースかどうか、サーバーが応答が得られます。しかし、クロスドメインサーバがAcceess・コントロール・アクセス原産の起源に応じて判断されます ( クライアントから)それが許さ源である場合、サーバはデータを返しますが、我々は、サーバーをセットアップすることができますので、それは、エラーメッセージではありませんAccess- Controlキーを許可- Orginプロパティを、クライアントのアドレスが書き込まれ、データを取得することができるようになります。
通常のクライアントは、次のようにサーバーコードは、サーバーに配置され、データを送信します。
import path from 'path';
import express from 'express'
//使用express框架创建web服务
const app = express();
//设置静态资源访问服务器功能,
//设置了之后,public目录下的文件可以直接用url访问
app.use(express.static(path.join(__dirname,'public')));
//拦截所有请求,为所有的请求设置响应头
app.use((req,res,next) => {
//配置允许的请求源,可以是多个地址,用逗号隔开,*表示允许所有的源
res.header('Access-Control-Allow-Orgin','*');
res.header('Access-Control-Allow-Methods','get,post');
next();//为请求放行,若是没有调用这个函数,那么请求不会往下去匹配
})
//设置路由
app.get('/',(req,res) =>{
var data = {name:'zhangsan',age:34};
res.send(data);
})
app.listen(3000);//监听端口
クッキー
従来のクライアントアクセスサーバーサーバーへの応答は、いくつかのケースではサーバ等の不便、時には必要であるホストへの見知らぬ人とされるたびにステートレスであるHTTPプロトコル、つまりクライアントを使用していくつかの識別情報を保持して、クライアントの保持は、ショッピングカートだけでなく、クライアントを追加するなど、いくつかの状態を、ログに記録しました。これを実現するために、我々は店舗情報にクッキーを使用することができ、ブラウザにクライアントの最初の訪問は、サーバがクライアントにクッキーを送信すると、クライアントは次の訪問は、サーバが知っていることができるようになります。このクッキーを運びます。
Ajax技術を使用してクロスドメインリクエストを送信するには、デフォルトでは、リクエストにクッキー情報を運ぶことはありません。
withCredentials:要求がクロスドメインに関連したとき、彼らはクッキーを運ぶかどうかを、指定されたデフォルトはfalse
とAccess-Control-Allow-Credentialsは:真運ぶクッキーは、クライアントが要求を送信することができたときに
クライアントのコアコード:
var loginForm = document.getElementById('loginform') ;
//将html表单对象转换为fromData表单对象
var formData = new FormData(loginForm);
var xhr = new XMLHttpRequest();
xhr.open('post','http://localhost:3301/login');
//当发送跨域请求时携带cookie
xhr.withCredentials = true;
xhr.send(formData);
xhr.onload = function () {
console.log(xhr.responseText);
}
サーバー側のコアコード:
app.use((req,res,next) => {
//配置允许的请求源,可以是多个地址,用逗号隔开,*表示允许所有的源
res.header('Access-Control-Allow-Orgin','*');
res.header('Access-Control-Allow-Methods','get,post');
//允许客户端发送跨域请求时携带cookie信息
res.header('Access-Control-Allow-Credentials',true);
next();//为请求放行,若是没有调用这个函数,那么请求不会往下去匹配
})