1.キーポイントを把握し、知識
##マスターキー
- 基本的な使い方を理解アヤックス
- 私たちは、XMLHttpRequestのオブジェクトを実装し、データ交換を使用します。
- onreadystatechangeにサーバーの応答情報を学ぶ(ステータスコード)
- オブジェクトは、ファイルをアップロードするために使用されますいるFormData
- アップロードを学ぶイベントオブジェクト(XMLHttpRequestの中のイベントオブジェクト)
##知識ポイント
- AJAXを使用して
- XMLHttpRequestオブジェクト
- いるFormDataオブジェクト
- アップロードイベントオブジェクト
2.ログの簡単なレビュー
図1に示すように、提案されたAJAXは、ユーザ名のニーズを確認します。
2、検証エラーの後、多くの問題をジャンプして解決した場合、
3.ユーザー名を検証する問題を解決するためのAjax
- Ajaxがある:アヤックス、すなわち "非同期JavaScriptとXML"(非同期JavaScriptとXML)
- AJAX基本的な使用:
- 新しいXMLHttpRequestオブジェクト。
let xhr = new XMLHttpRequest();
- パラメータ設定要求
xhr.open("get","/checkUser",true); //true是异步,false是同步
- 戻り値を受け取ります
xhr.onload = function(){
let res = JSON.parse(xhr.responseText);
}
- サーバ要求を送信します
xhr.send();
ケースは、非同期AJAXなしリフレッシュ検証ユーザー名によって達成されます。
login.css:
.loginContainer{
margin: 0 auto;
width: 600px;
text-align: center;
padding-top: 20px;
padding-bottom: 50px;
border: 1px solid;
}
.loginContainer input{
margin-bottom: 20px;
}
.loginStyle{
width: 160px;
height: 40px;
background: rgb(50,203,77);
color: white;
font-size: 17px;
}
.inputStyle{
width: 200px;
height: 30px;
padding: 5px;
outline: none;
}
.inputStyle:focus{
border: 1px solid rgb(50,203,77);
}
form{
position: relative;
}
.exchange{
position: absolute;
top:8px;
right: 65px;
color: red;
display: none;
}
user.json:
[
{
"id":1,
"username":"zhangsan",
"pwd":"123"
},{
"id":2,
"username":"lisi",
"pwd":"123"
}
]
login.js:
const Koa = require("koa");
const Router = require("koa-router");
const static = require("koa-static");
// const views = require("koa-views");
const userData = require("./data/user.json");
let app = new Koa();
let router = new Router();
app.use(static(__dirname + "/static"));
//前面页面直接放到static里时,只能通过login.html访问,不能通过/直接访问
router.get("/checkUser", (cxt, next) => {
let username = userData.find(item=>item.username === cxt.query.username);
console.log(username);
if(username){
cxt.body = {
status:1,
msg:"用户名正确"
};
}else{
cxt.body = {
status:0,
msg:"用户名错误"
};
}
});
app.use(router.routes());
app.listen("9090");
login.htmlと:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<link rel="stylesheet" href="css/login.css" />
<title>Document</title>
</head>
<body>
<div class="loginContainer">
<h1>登录</h1>
<form action="/checkUser" method="post">姓名:
<input class="inputStyle" type="text" name="username" />
<div class="exchange">用户名错误</div>
<br />密码:
<input class="inputStyle" type="password" name="pwd" /><br />
<input class="loginStyle" type="submit" value="登录" />
</form>
</div>
<script>
{
//鼠标失去焦点时,进行无刷新验证
let username = document.querySelectorAll("input");
let exchange = document.querySelector(".exchange");
username[0].onblur = function(){
let xhr = new XMLHttpRequest();
xhr.open("get","/checkUser?username="+this.value,true);//true表示异步发送请求,false同步发送请求
xhr.onload = function() {
//注意返回数据是从XMLHttpRequest对象中获得的
let res = JSON.parse(xhr.responseText);
// console.log(JSON.parse(xhr.responseText).msg);
// console.log(xhr.response);
exchange.style.display = "block";
exchange.innerHTML = JSON.parse(xhr.responseText).msg;
console.log(res.status);
if(res.status === 1){
//获取到的数据是JSON格式的,需要将其转为对象
exchange.style.color = "green";
}else{
exchange.style.color = "red";
}
}
xhr.send();
}
}
</script>
</body>
アヤックスの詳細な説明のために4
4.1get上のご注意
- GETパラメータparmas渡し
- 取得し、質量参加URLを通じて問題をクエリ文字列
二つの方法で渡すパラメータを取得:
- queryStringによる質量の参加は長さ制限があり、クエリ文字列、デフォルトは2048です
- /取得/ ID
道パラメータ通過点に注意してください。
- GETリクエストをクエリ文字列されて通過し得る/ポストリクエストモードは、2つの概念である、代わりのパラメータ渡しを使用してパラメータをクエリ文字列、POSTパラメータはまた、クエリ文字列を介して送信することができます。
- クエリ文字列場合背景受信アドレスを介して通過するパラメータが影響されない;しかし、GET / ID送信モードを使用する場合/基準背景マスト/ GET /:IDモード受信パラメータを、パラメータ値がctx.paramsにより得られます。
モードを渡すパラメータのqueryString:上記の例
モードを渡すパラメータ「/リクエストアドレス/パラメータ」:使用して「/アドレス要求/:パラメータは、」アドレスを受信し、パラメータ値がctx.paramsを使用して取得しました
<body>
<button>点击发送get请求</button>
<script>
{
//通过/get/3的方式进行传参,后台通过/get/:id进行获取,ctx.params得到具体参数值
document.querySelector("button").onclick = function(){
let xhr = new XMLHttpRequest();
xhr.open("get","/getInfo/1");
xhr.onload = function(){
console.log(xhr.responseText);//{"status":1,"msg":"请求成功"}
}
xhr.send();
};
}
</script>
</body>
login.js:
//get请求
router.get("getInfo","/getInfo/:id",ctx=>{
console.log(ctx.params);//{ id: '1' }
ctx.body = {
status:1,
msg:"请求成功"
};
});
4.2post上のご注意
、のqueryStringによるもの質量参加一般ポストためのqueryString質量参加制限された長さ(サーバー制限)、デフォルト2048。
ポスト参照パラメータ受け渡しがHTTPボディを通過させ、体をフォーマットをコードするパラメータを渡すように設定されなければなりません。フォーマット形式<FORM ACTION = ""のenctype =コードデフォルトでフォーム "アプリケーション/ x-www-form-urlencodedで"> </ form>を。フォームのフォームを省略することができるが、ときAJAX要求を省略することができません。
注意点:
- データを送信する場合、HTTPヘッダのテキスト形式を設定します。
- ヘッダ情報を取得:getAllResponseHeaders又はgetResponseHeader。
- 送信テキストデータを使用すると、HTTPヘッダのフォーマットを設定する必要があります。
xhr.setRequestHeader("Content-type","application/x-www-form-urlencoded"); //默认编码
xhr.setRequestHeader("Content-type","multipart/form-data"); //二进制编码,上传文件时使用
xhr.setRequestHeader("Content-type","application/json"); //json编码:传输数据也需要时JSON格式
例:ポスト要求の使用は、バックグラウンドKOA体モジュールがパラメータを取得するために使用する必要があります
<body>
<button>点击发送post请求</button>
<script>
{
//通过/get/3的方式进行传参,后台通过/get/:id进行获取,ctx.params得到具体参数值
document.querySelector("button").onclick = function(){
let xhr = new XMLHttpRequest();
xhr.open("post","/getPostInfo");
xhr.onload = function(){
console.log(xhr.responseText);//{"status":1,"msg":"请求成功"}
}
//设置正文请求头
xhr.setRequestHeader("content-type","application/x-www-form-urlencoded");
let data = "username=zs&age=20";
xhr.send(data);
};
}
</script>
</body>
const koaBody = require("koa-body");
app.use(koaBody());
//post请求
router.post("/getPostInfo",ctx=>{
console.log(ctx.request.body);//{ username: 'zs', age: '20' }
ctx.body = {
status:1,
msg:"请求成功"
};
});
場合は、HTTPヘッダーテキストJSONとしてフォーマット:JSONデータ伝送フォーマットも必要とされ、あなたはJSONにデータをフォーマット)(JSON.stringifyを使用する必要があります。
//正文请求头设置为json时,传输数据也需要是JSON格式
xhr.setRequestHeader("content-type","application/json; charset=utf-8");
let data = JSON.stringify({
username:'zs',
age:12
});
- ヘッダー情報を取得しますgetAllResponseHeaders()は、ヘッダー情報を取得することを、すべてのヘッダー情報やgetResponseHeader(「リクエスト・ヘッダー属性」)を取得します。
xhr.onload = function(){
console.log(xhr.responseText);//{"status":1,"msg":"请求成功"}
//获取所有头部信息
console.log(xhr.getAllResponseHeaders());
//获取某个头部信息
console.log(xhr.getResponseHeader("content-type"));//application/json; charset=utf-8
}
結果:すべてのヘッダー情報
日付:水曜日、2019年9月18日午前1時59分50秒GMTの
接続:キープアライブ
のコンテンツの長さ:33
コンテンツタイプ:アプリケーション/ JSON。文字セット= UTF-8
4.3同期および非同期AJAX
- セット非同期要求や他の要求は、コードの実装に影響を与えません。
- 同期実行を設定するときに、要求した後に実行されてもよい他の要求またはコードのように、実行されます
非同期:非同期設定要求は、コードまたは他の要求の実行には影響しません
<body>
<button>按钮一</button>
<button>按钮二</button>
<script>
{
let btns = document.querySelectorAll("button");
btns[0].onclick = function(){
let xhr = new XMLHttpRequest();
xhr.open("get","/getInfo/2",true);
xhr.onload = function(){
console.log(xhr.responseText);
}
xhr.send();
}
//点击第二个按钮时进行打印
btns[1].onclick = function(){
console.log("按钮二打印。。。");
}
}
</script>
</body>
結果:要求を印刷するボタンは2つのボタンの結果には影響しません。
非同期:同期実行を設定するときは、要求した後に実行されてもよい他の要求またはコードのように、実行されます
xhr.open("get","/getInfo/2",false);
結果:
5.onreadystatechange
5.1 onreadystatechangeに
onreadystatechangeに:readyStateのが変化するたびにサーバ応答を処理してそこ機能、onreadystatechangeに機能が実行されます。
5.2 readyStateの
readyStateの:状態サーバーの応答情報が。
- 0:要求が初期化されていません(プロキシが作成されますが、まだ(オープン呼び出しです)メソッド)
- 1:サーバー接続が確立される(open`メソッドが呼び出されています `)
- 2:要求( `send`メソッドが呼び出されており、状態及びヘッドがすでに利用可能である)を受信しました
- 3:プロセスの要求(ダウンロードには、 `responseText`プロパティは、既に一部のデータが含まれています)
- 4:(ダウンロード操作が完了した)要求が完了した、と応答が準備ができています
5.3状態の一般的なステータスコード
HTTPステータスコード | 説明 |
---|---|
100 |
続行。残りの部分は、リクエストを送信、応答に続きます |
200 |
成功 |
301 |
永久的な動き。新しい場所に永続的にリソースを要求 |
302 |
一時的な動き。新しい場所にゼロリソース要求 |
304 |
未修飾。リソースに対する最後の要求が変更されていないよりも、応答は、リソースコンテンツが含まれていません |
401 |
無許可には認証が必要です |
403 |
禁止されています。要求が拒否されました |
404 |
見つからない、サーバーはリソースを見つける必要がありません |
500 |
内部サーバーエラー。サーバーでエラーが発生しましたし、要求を満たすことができません |
503 |
サーバーを利用できません。一時的なサービスが過負荷と要求を処理できません |
例:
<body>
<button>点击</button>
<script>
document.querySelector("button").onclick = function(){
let xhr = new XMLHttpRequest();
xhr.open("get","/getInfo/3",true);
xhr.onreadystatechange = function(){
//判断服务求响应状态为4和返还状态200(成功)
if(xhr.readyState == 4){
if(xhr.status == 200){
console.log(xhr.responseText);//{"status":1,"msg":"请求成功"}
}
}
}
xhr.send();
};
</script>
</body>
実際には、サーバーの応答情報を返すステータスコードがonloadイベントを使用している:onloadイベントは、より簡潔な推奨されます
xhr.onload = function(){
console.log(xhr.readyState);//4
console.log(xhr.status);//200
console.log(xhr.responseText);//{"status":1,"msg":"请求成功"}
}
5.4戻り値のデータタイプ
- サーバーは、JSONデータを返しました:xhr.responseTextを取得するには
xhr.responseText //来获取
- サーバーのXMLデータが返されました:
- xhr.responseXML //値を取得
- コンテンツタイプのコンテンツctx.setに設けられた応答サーバ(「コンテンツタイプ」、「テキスト/ HTML」)。
- (ケースバック型コンテンツ・タイプが指定されていない)は、遠位XML書き換え:xhr.overrideMimeType(「text / xmlで、文字セット= UTF-8」);プロパティは間にスペースならないことに注意してください
xhr.responseXML //获取值
例:
フロントエンドのHTML:
<body>
<button>点击获取XML数据</button>
<script>
{
document.querySelector("button").onclick = function(){
let xhr = new XMLHttpRequest();
xhr.open("get","/getXMLInfo",true);
//如果后台没有设置XML的content-type,前端就必须重写格式
xhr.overrideMimeType('text/xml;charset=utf-8');
xhr.onload = function(){
//获取XML格式数据
console.log(xhr.responseXML);
console.log(xhr.responseXML.getElementsByTagName("name")[0]);
//获取原始数据
console.log(xhr.response);
}
xhr.send();
}
}
</script>
</body>
背景:
//获取XML数据
router.get("/getXMLInfo",ctx=>{
ctx.set("content-type","text/xml");
//注意这里反引号和xml内容不能换行
ctx.body = `<?xml version='1.0' encoding='utf-8' ?>
<books>
<nodejs>
<name>nodeJS实战</name>
<price>52.0元</price>
</nodejs>
<react>
<name>react进阶</name>
<price>56.0元</price>
</react>
</books>`;
});
結果:
背景を防ぐために、前にXML形式を書き換える必要性をXMLコンテンツタイプを書いていません。
xhr.overrideMimeType('text/xml;charset=utf-8');
ファイルのアップロードに6.いるFormData
オブジェクトの作成6.1いるFormData
注意点:
- 配列で取得した<入力タイプ=「ファイル」クラス=「myfileのは」>クラスは、ファイル属性です。
- 新しいいるFormDataを通じてファイルアップロードオブジェクトを作成します();
- formData.append(名前、値);名名が受信背景と一致している必要があり、値は通常のデータファイルであってもよいです
- ファイルのアップロードはテキストの方法によって送信されなければならない、それはPOSTリクエストを使用する必要があり、コンテンツタイプは自動的いるFormDataの使用を設定しますが、手動で設定する必要はありません。
- バックグラウンドデータを受信すると、name属性()遠位ファイルに対応するデータ又は追記を得ることができます
- その後、モジュールに対応するファイルFSをダンプします。その一時的なパスctx.request.files.img.pathファイルは、一時的なパスにサーバファイルへのパスをダウンダンプ
- これは、可能なフォルダのアクセス許可の問題は、手動でダンプファイルのパーミッションを開く必要があります。そして、フォルダは、フォルダを作成し、存在しません。
例:
フロント:
<body>
<input type="file" class="myfile">
<button>点击上传</button>
<script>
document.querySelector("button").onclick = function(){
let myfile = document.querySelector(".myfile");
//files属性返回的是类数组
let files = myfile.files;
//创建FormData对象,进行上传
let formData = new FormData();
//img表示name,相当于form表单中的name属性,file[0]表示要上传的单个文件
formData.append("img",files[0]);
//其他的数据,也可以进行传输
formData.append("username","张三");
//文件上传必须通过正文方式进行传递,所以必须使用post请求
//使用FormData时会自动对content-type进行设置,就不需要再进行手动设置
let xhr = new XMLHttpRequest();
xhr.open("post","/upload",true);
xhr.onload = function(){
console.log(xhr.responseText);
};
xhr.send(formData);
};
</script>
</body>
背景:
const Koa = require("koa");
const Router = require("koa-router");
const static = require("koa-static");
const koaBody = require("koa-body");
const fs = require("fs");
let app = new Koa();
let router = new Router();
app.use(static(__dirname + "/static"));
//上传文件时,必须设置允许文件上传,否则接收不了
app.use(koaBody({
multipart:true
}));
//上传文件
router.post("/upload",ctx=>{
//通过前端append()中的name属性即可获取到对应数据或文件
// console.log(ctx.request.body);//{ username: '张三' }
// console.log(ctx.request.files.img);
//通过fs模块对相应文件进行转存即可
//ctx.request.files.img.path即文件的临时路径,对临时路径中的文件转存到服务器下路径即可
let fileData = fs.readFileSync(ctx.request.files.img.path);
//文件转存时有可能出现文件夹权限问题,需要手动开启权限
//判断文件夹不存在,需要先创建文件夹
if(!fs.existsSync("static/imgs")){
fs.mkdirSync("static/imgs/");
}
fs.writeFileSync("static/imgs/"+ctx.request.files.img.name,fileData);
ctx.body = {
status:1,
msg:"文件上传成功"
};
});
app.use(router.routes());
app.listen("8888");
結果:{ "ステータス":1、 "msgが": "ファイルが正常にアップロード"}
6.2モニターアップロードの進捗--uploadイベント
次のイベントは、アップロードイベントの下に、次のとおりです。
- アップロードを開始onloadstart
- (:、:現在のファイルサイズをアップロードevt.loaded、合計サイズが送信されるevt.total)でonprogressデータ転送
- アップロード処理が終了するonabort(アップロードxhr.abortをキャンセル())
- ONERRORのアップロードに失敗しました
- onloadイベント正常にアップロード
- onloadendアップロードが(成功したか否か)が完了しました
例を監視し、ファイルアップロードの進捗:
注意点:
- 、現在のファイルサイズ/時間差、ドキュメントのアップロード速度(onloadstartとonprogress時間差と時間差ファイルアップロードされたファイルのサイズが必要)、ファイルアップロードの速度を監視します。
- 処理ユニットは、/ sのキロバイト/秒bをアップロードする必要があります。
ファイルのアップロードページ:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<style>
.progressSpan{
display: none;
color: seagreen;
}
</style>
</head>
<body>
<input type="file" class="myfile">
进度:<progress value="0" max="100"></progress> <span class="progressSpan">10%</span>
速度:<span class="speed">20b/s</span><br><br>
<button>点击上传</button>
<button>取消上传</button>
<script>
{
let btns = document.querySelectorAll("button");
let xhr = new XMLHttpRequest();
btns[0].onclick = function(){
let sTime = 0;//文件开始上传时间
let eTime = 0;//文件开始上传时间
let fileInitSize = 0;//文件开始上传大小
xhr.open("post","/fileUpload",true);
//获取上传文件
let file = document.querySelector(".myfile").files[0];
let formData = new FormData();
formData.append("imgFile",file);
//upload事件监控文件上传进度
xhr.upload.onloadstart = function(){
console.log("文件开始上传");
sTime = new Date().getTime();
fileInitSize = 0;
};
xhr.upload.onprogress = function(evt){
console.log("文件上传中");
//在onprogress事件中监控上传进度
let progress = (evt.loaded / evt.total * 100).toFixed(0);
//将进度进行显示
document.querySelector("progress").value = progress;
document.querySelector(".progressSpan").style.display = "inline-block";
document.querySelector(".progressSpan").innerHTML = progress+"%";
//监控文件上传速度(需要onloadstart和onprogress的时间差,及时间差内文件已上传的文件大小)
eTime = new Date().getTime();
//需要将时间差转为秒s
let diffTime = (eTime-sTime)/1000;
//各个进度文件上传的文件大小
let curFileSize = evt.loaded;
let diffFileSize = curFileSize - fileInitSize;
//获取上传速度(需要处理上传的单位b/s kb/s)
let speed = diffFileSize/diffTime;
let unit = "";
if(speed/1024>1){
speed = speed/1024;
unit = "b/s";
}
if(speed/1024>1){
speed = speed/1024;
unit = "kb/s";
}
document.querySelector(".speed").innerHTML = speed.toFixed(2)+unit;
//使用当前文件大小/时间差 即文件上传速度
sTime = eTime;
fileInitSize = curFileSize
};
xhr.upload.onabort = function(){
console.log("取消文件上传");
};
xhr.upload.onerror = function(){
console.log("文件上传失败");
};
xhr.upload.onload = function(){
console.log(xhr.responseText);
};
xhr.upload.onloadend = function(){
console.log("文件上传完成");
};
xhr.send(formData);
};
btns[1].onclick = function(){
//取消文件上传方法
xhr.abort();
};
}
</script>
</body>
</html>
バックグラウンド処理:
//监控文件上传进度
router.post("/fileUpload",(ctx,next)=>{
//通过前端append()中的name属性即可获取到对应数据或文件
//ctx.request.files.imgFile.path即文件的临时路径,对临时路径中的文件转存到服务器下路径即可
let fileData = fs.readFileSync(ctx.request.files.imgFile.path);
//判断文件夹不存在,需要先创建文件夹
if(!fs.existsSync("static/imgs")){
fs.mkdirSync("static/imgs/");
}
fs.writeFileSync("static/imgs/"+ctx.request.files.imgFile.name,fileData);
ctx.body = {
status:1,
msg:"文件上传成功"
};
});
結果:
7.リコール
1.ajax基本的な使用:()xhr.open、のXMLHttpRequestオブジェクトを作成し、xhr.onload、xhr.send()
AJAXで使用されている2.get /ポスト
3.ajax成功リターン:onloadイベント
4.データ形式は返さ:応答、responseText、responseXMLを
、いるFormDataオブジェクトを作成しますform.append(名前、値):5.FormDataは、オブジェクト
各ファイルのアップロードのためのイベントの監視方法:6.uploadイベントオブジェクト