HTTP 請求參數之三種格式

下面內容是關於 Query String ParametersForm DataRequest Payload 三種格式的區別。主要是由於 Content-Type 與請求方式 method 不一樣,致使傳遞的數據格式不一樣。html

Content-Type: [media-type];[charset];boundary

原生 ajax 請求默認 Content-Type: text/plain;charset=UTF-8git

常見的媒體格式:github

媒體格式

請求參數格式

*1. Query String Parameters 格式: ?key=value&key=valueweb

參數會以 url string 的形式進行傳遞,即?後的字符串則爲其請求參數,並以&做爲分隔符。經常使用在 GET 請求方式時使用。 其餘請求方式也可使用,拼接在接口地址 `url?` 後面。

![Query String Parameters](https://raw.githubusercontent.com/wqjiao/Points-Issues/master/assets/QueryStringParameter.png)

*2. Form Data 格式:key=value&key=value 鍵值對形式ajax

  • Content-typeapplication/x-www-form-urlencoded;charset=utf-8 時,參數會以 Form Data 的形式(數據爲 String 鍵值對格式)傳遞給接口,而且不會顯示在接口 url 上。
let data = {
    username: 'wqjiao',
    password: '111111',
}
xhr.send(QS.stringify(data));

Form Data

  • 對錶單提交和文件上傳時作特殊處理,須要使用 new FormData() 方法處理後傳遞給接口,Content-typemultipart/form-data; boundary=----WebKitFormBoundarys9jOoKcA1Kwn9sYS 格式。
const formData = new FormData();
formData.append('label', 'ID_photo-front');
formData.append('subId', 'fa6abb94000a4ba1b19a43e60eba1516');
formData.append('file', fileList[0]);

fetch('http://192.168.1.128:5022/tool/file/upload', {
    method: 'POST',
    headers: {
        'Authorization': '89199cf3294520765904d47c2c570c1b',
    },
    body: formData,
    cridentials: 'include',
    mode: 'no-cors',
    processData: false,
    cache: false,
    contentType: false,
});

FormData:multipart/form-data

  • 補充說明json

    1. 服務器爲何會對錶單提交和文件上傳作特殊處理,由於表單提交數據是名值對的方式,且Content-Type爲application/x-www-form-urlencoded,而文件上傳服務器須要特殊處理,普通的post請求(Content-Type不是application/x-www-form-urlencoded)數據格式不固定,不必定是名值對的方式,因此服務器沒法知道具體的處理方式,因此只能經過獲取原始數據流的方式來進行解析。
    2. processData: false --> 由於 data 值是 formdata 對象,不須要對數據作處理。
    3. cache: false --> 上傳文件不須要緩存。
    4. contentType: false --> 由於是由 <form> 表單構造的 FormData 對象,且已經聲明瞭屬性 enctype="multipart/form-data",因此這裏設置爲 false。
    5. xhrFields: { withCredentials: true }, 跨域請求設置

*3. Request Payload 格式:{key: value, key: value} (後端通過反序列化獲得對象)後端

當 `Content-type` 爲 `application/json;charset=utf-8` 時,參數會以 `Request Payload` 的形式(數據爲 json 格式)傳遞給接口,而且不會顯示在接口 url 上。

```js
let data = {
    username: 'wqjiao',
    password: '111111',
}
xhr.send(Qs.stringify(data));
```

Request Payload

let Ajax = {
    get: function (url, fn) {
        // XMLHttpRequest對象用於在後臺與服務器交換數據   
        let xhr = new XMLHttpRequest();
        xhr.open('GET', url, true);
        xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
        xhr.onreadystatechange = function () {
            // readyState == 4說明請求已完成
            if (xhr.readyState == 4 && xhr.status == 200 || xhr.status == 304) {
                // 從服務器得到數據 
                fn.call(this, xhr.responseText);
            }
        };
        xhr.send();
    },
    // data 應爲'a=a1&b=b1'這種字符串格式,在jq裏若是data爲對象會自動將對象轉成這種字符串格式
    post: function (url, data, fn) {
        let xhr = new XMLHttpRequest();
        xhr.open("POST", url, true);
        // xhr.open("POST", '/response.json', true);
        xhr.setRequestHeader('Accept', 'application/json')
        xhr.setRequestHeader('Authorization', 'bb850ec168d55eedcb0b47ac4e7c9d6b')
        // 添加http頭,發送信息至服務器時內容編碼類型
        xhr.setRequestHeader("Content-Type", "application/json");
        // xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
        xhr.onreadystatechange = function () {
            if (xhr.readyState == 4 && (xhr.status == 200 || xhr.status == 304)) {
                fn.call(this, xhr.responseText);
            }
        };

        // application/json 格式:{key: value, key: value}
        xhr.send(JSON.stringify(data));
        // application/x-www-form-urlencoded 格式:key=value&key=value
        // xhr.send(Qs.stringify(data));
    }
}

new FormData(form)

  1. 獲取數據跨域

    • 獲取一個控件的 value :formData.get('name');
    • 獲取一組控件 name 爲 username 的 values,返回數組 :formData.getAll('username');
  2. 添加數據 formData.append('username', 'qq');
  3. 設置修改數據 formData.set("username", 'wqjiao');

    注意:若是 formData 中不存在 username 字段,那麼,js不會報錯,而是直接新增當前鍵值對。數組

  4. 判斷是否存在該數據,返回 Boolean 類型 formData.has('username');
  5. 刪除某數據 formData.delete('username');
  6. 返回全部的鍵值對:formData.entries()

    formData.entries() 方法返回一個 iterator 對象 ,此對象能夠遍歷訪問 formData 中的鍵值對。其中鍵值對的 key 是一個 USVString 對象;value 是一個 USVString , 或者 Blob 對象。緩存

  7. 實例

    <form id="myForm">
        <input type="text" name="name" placeholder="請輸入你的名字" />
        <input type="password" name="password" placeholder="請輸入你的密碼" />
    
        <input type="text" name="n1" />
        <input type="text" name="n1" />
    
        <input type="submit" id="submitBtn" value="提交" />
    </form>
    <script>
        // 表單初始化
        let form = document.getElementById('myForm');
        let submitBtn = document.getElementById('submitBtn');
    
        submitBtn.addEventListener('click', function (e) {
            e.preventDefault();
    
            let formData = new FormData(form);
            // 獲取數據
            let name = formData.get('name');
            let arr = formData.getAll('n1');
    
            // 添加數據
            formData.append('username', 'wqjiao');
            // 判斷是否存在 name 爲 deletename
            if (formData.has('deletename')) {
                // 修改數據
                formData.set("deletename", '123456');
            }
    
            // 刪除數據
            formData.delete('password');
    
            // 返回全部的數據,遇到重複的 name,保留最新的值
            let data = {};
            for(let name of formData.entries()) {
                if (name) {
                    data[name[0]] = name[1];
                }
            }
    
            console.log(name, arr, data);
    
            // 請求接口
            let xhr = new XMLHttpRequest();
            xhr.open('POST', 'response.json', true);
            xhr.send(formData);
            
        }, false);
    
    </script>

推薦閱讀

相關文章
相關標籤/搜索