前面と背面側との対話(アヤックスいるFormDataオブジェクトとアップロードファイル)

1.キーポイントを把握し、知識

##マスターキー

  1. 基本的な使い方を理解アヤックス
  2. 私たちは、XMLHttpRequestのオブジェクトを実装し、データ交換を使用します。
  3. onreadystatechangeにサーバーの応答情報を学ぶ(ステータスコード)
  4. オブジェクトは、ファイルをアップロードするために使用されますいるFormData
  5. アップロードを学ぶイベントオブジェクト(XMLHttpRequestの中のイベントオブジェクト)

##知識ポイント

  1. AJAXを使用して
  2. XMLHttpRequestオブジェクト
  3. いるFormDataオブジェクト
  4. アップロードイベントオブジェクト

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を通じて問題をクエリ文字列

二つの方法で渡すパラメータを取得:

  1. queryStringによる質量の参加は長さ制限があり、クエリ文字列、デフォルトは2048です
  2. /取得/ 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要求を省略することができません。

注意点:

  1. データを送信する場合、HTTPヘッダのテキスト形式を設定します。
  2. ヘッダ情報を取得: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
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データが返されました:
  1. xhr.responseXML //値を取得
  2. コンテンツタイプのコンテンツctx.setに設けられた応答サーバ(「コンテンツタイプ」、「テキスト/ HTML」)。
  3. (ケースバック型コンテンツ・タイプが指定されていない)は、遠位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

注意点:

  1. 配列で取得した<入力タイプ=「ファイル」クラス=「myfileのは」>クラスは、ファイル属性です。
  2. 新しいいるFormDataを通じてファイルアップロードオブジェクトを作成します();
  3.  formData.append(名前、値);名名が受信背景と一致している必要があり、値は通常のデータファイルであってもよいです
  4. ファイルのアップロードはテキストの方法によって送信されなければならない、それはPOSTリクエストを使用する必要があり、コンテンツタイプは自動的いるFormDataの使用を設定しますが、手動で設定する必要はありません。
  5. バックグラウンドデータを受信すると、name属性()遠位ファイルに対応するデータ又は追記を得ることができます
  6. その後、モジュールに対応するファイルFSをダンプします。その一時的なパスctx.request.files.img.pathファイルは、一時的なパスにサーバファイルへのパスをダウンダンプ
  7. これは、可能なフォルダのアクセス許可の問題は、手動でダンプファイルのパーミッションを開く必要があります。そして、フォルダは、フォルダを作成し、存在しません。

例:

フロント:

<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>&nbsp;&nbsp;<span class="progressSpan">10%</span>&nbsp;&nbsp;
    速度:<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イベントオブジェクト

公開された95元の記事 ウォンの賞賛115 ビュー120 000 +

おすすめ

転載: blog.csdn.net/qq_34569497/article/details/100917080