Ajax學習第五天

Ajax學習第五天——FormData及同源政策

背景:由前幾天的學習可以知道,當對錶單數據進行提交的時候,Ajax需要我們指明需要提交的屬性及數據並進行拼接,在這之前,我們必須手動獲取對應控件的相關內容,一旦數據量過大,就很容易造成拼接錯誤等問題,所以提出了FormData這一解決方案。

  • FormData對象的作用
    1. 模擬HTML表單,相當於將HTML表單映射成表單對象,自動將表單對象中的數據拼接成請求參數的格式;
    2. 異步上傳二進制文件(例如:圖片 視頻及音頻文件)。

  • FormData對象的使用
    1. 準備HTML表單,不用設置請求地址及請求方式,也不用將input控件中的按鈕設置爲submit,設置爲button即可,因爲若設置爲submit方式,表單會自動進行提交,從而使FormData不生效,值得注意的是,必須爲需要提交數據的控件設置name屬性

    <form id="form">
        <input type="text" name="username">
        <input type="password" name="password">
        <input type="button" id="btn" value="提交">
    </form>
    
  1. 利用FormData構造函數,將HTML表單轉化爲FormData對象
    var form = document.getElementById('form');
    var formData = new FromData(form);

  2. 提交表單對象,採用此方法提交表單時,不支持get方法
    xhr.send(formData);

  • FormData對象的實例方法
  1. 獲取表單對象中屬性的值
    formData.get('key');
  2. 設置表單對象中屬性的值,如果表單控件不存在,則會自動創建這個表單屬性
    formData.set('key','value');
  3. 刪除表單對象中屬性的值
    formData.delete('key');
  4. 向表單對象中追加屬性值,它可以在空的表單對象中追加值
    formData.append('key','value');
    與 set 方法的區別:在屬性名已存在的情況下,set 方法會覆蓋已有鍵名的值,append 會保留兩個值,但是服務器端需要響應的設置,否則,仍然傳遞最後一次的值。
  • FormData對二進制文件的上傳及文件上傳進度的展示
    代碼如下:
<!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>
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css"
        integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous">
</head>
<body>
    <div class="container">
        <div class="form-group">
            <label>請選擇文件</label>
            <input type="file" id="file">
            <br/>
            <div class="progress">
                <div class="progress-bar" style="width: 0%;" id="progress">0%</div>
            </div>
        </div>
    </div>
    <script>
        //獲取文件控件
        var file = document.getElementById('file');
        //對文件控件田間發生改變事件
        file.onchange = function () {
            //創建空的FormData構造函數
            var formData = new FormData();
            //將file控件中選擇的文件追加到formData中 
            // 第一個參數開發過程中由後端人員提供  第二個參數代表選擇的文件
            formData.append('attrName',this.files[0]);
            //創建Ajax對象
            var xhr = new XMLHttpRequest();
            //配置Ajax對象
            xhr.open('post','http://localhost/foemData');
            //在文件上傳的過程中持續觸發
            xhr.upload.onprogress = function(ev){
                //ev.loaded 文件已經上傳了多少
                //ev.total 上傳文件總大小
                var pro = (ev.loaded / ev.total)*100+'%';
                //獲取進度條
                var progress = document.getElementById('progress');
                //設置進度條的寬度
                progress.style.width = pro;
                //設置進度條的數值
                progress.innerHTML = pro;
            }
            xhr.send(formData);
            xhr.onload = function(){
                console.log(xhr.responseText);
            }
        }
    </script>
</body>
</html>
  • FormData文件上傳圖片即使預覽
    在我們將圖片上傳到服務器以後,服務器通常都會將圖片地址作爲響應數據傳遞到客戶端,客戶端可以從響應數據中獲取圖片地址,然後將圖片再顯示到頁面中,值得注意的是,客戶端得到地址後,需要動態的創建img標籤,即首先var img = document.createElement('img');,再採用box.appendChild(img);的方式添加到頁面上,如果直接將圖片地址賦值給img的src,客戶會看到圖片的加載過程,影響用戶體驗;在服務端,同樣的需要設置,應該引入表單解析對象,即formidable。

接下來是有關昨天做行政區聯動碰到的問題,大相徑庭。

  • 同源政策
    Ajax的請求限制:Ajax只能向自己的服務器發送請求,比如說,A網站的服務器端有A的HTML文件,B網站的服務器端有B的HTML頁面,此時,A可以向自己的服務器發送Ajax請求,B也可以向自己的服務器發送Ajax請求,但是A不能向B的服務器發送Ajax請求,B也同理。
  • 什麼是同源
    如果兩個頁面擁有相同的域名,協議及端口,那麼我們稱這兩個頁面是同源的,其中只要有一個不同,都是不同源的。
  • 同源政策的目的
    同源政策是爲了保證用戶信息的安全,防止惡意的網站竊取數據,最初的同源政策是指A網站在客戶端防止的Cookie,B網站是不能訪問的。
  • 使用JSONP解決同源限制問題
    JSONP:json with padding的簡稱 它不屬於Ajax請求,但它可以模擬Ajax請求
  • 使用JSONP解決同源限制問題的步驟
  1. 將不同源的服務器端請求地址寫在script標籤的src屬性中,因爲script標籤不受同源政策的影響
    <script src="www.example.com"></script>
  2. 服務器端響應數據必須是一個函數的調用,真正要發送給客戶端的數據需要作爲函數調用的參數
    const data = 'fn({name:'zhangSan',age:'20'})';
    res.send(data);
  3. 在客戶端全局作用域下定義函數fn,這個函數需要寫在script標籤的前面
    function fn(data){ }
  4. 在fn函數內部對服務器端返回的數據進行處理
    function fn(data){console.log(data)}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章