鍍金池/ 問答/HTML/ 請問上傳文件如何使用put形式上傳。我寫了一個demo,但是后臺接收的一直是空。

請問上傳文件如何使用put形式上傳。我寫了一個demo,但是后臺接收的一直是空。

是我這個put形式傳遞的參數(shù)有問題嗎?put形式傳遞文件不能這樣嗎?望大神能為我解答一二。

clipboard.png

<!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>
</head>
<body>
    <input id="file" name="img" type="file"/>
</body>
<script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.js"></script>
<script>
    $('#file').on('change',function(){
        var formData = new FormData();
        formData.append("img", $("#file")[0].files[0]);
        console.log(formData,'form', $("#file")[0].files[0])
        $.ajax({
            url: "xxx",
            type: "put",
            data: formData,
            processData: false,
            contentType: false,
            xhrFields:{withCredentials: true},
            success: function(response){
                console.log(response)
                    // 根據(jù)返回結(jié)果指定界面操作
            }
        });
    })
</script>
</html>
回答
編輯回答
敢試

首先,先解析一下 POSTPUT 的區(qū)別

HTTP/1.1協(xié)議中共定義了8中請求方法:GET、HEAD、POST、PUT、DELETE、CONNECT、OPTIONS、TRACE,其中用的相對較多的有下面四種:

GET      獲取資源
PUT      更新或創(chuàng)建資源
POST     創(chuàng)建資源
DELETE   刪除資源

RESTful api則充分利用了HTTP協(xié)議,每個資源對應(yīng)一個具體的URI,然后利用不同的HTTP操作對應(yīng)增刪改查,如:

POST       /uri       創(chuàng)建
DELETE     /uri/xxx   刪除
PUT        /uri/xxx   更新或創(chuàng)建
GET        /uri/xxx   查看

可以看到,GET和DELETE對應(yīng)的操作非常明確,但是POST與PUT都可以進(jìn)行資源的創(chuàng)建,那么什么時候用POST什么時候用PUT呢

這就需要了解HTTP協(xié)議中的另一個重要性質(zhì):冪等

什么是冪等

要理解PUT和POST的區(qū)別,還要知道HTTP協(xié)議中的一個重要性質(zhì),冪等(Idempotence):

Methods can also have the property of “idempotence” in that (aside from error or expiration issues) the side-effects of N > 0 identical requests is the same as for a single request.

什么個意思呢?HTTP協(xié)議中的冪等指的是一個資源無論請求多少次,對他產(chǎn)生的副作用是一樣的

GET操作是安全的,也就是不管操作多少次,資源的狀態(tài)都不會改變,所以GET也是冪等的
PUT和DELETE是冪等的,比如我用PUT或者DELETE修改一個資源,不管操作多少次,每次操作后的結(jié)果并沒有什么不同
POST操作既不是安全的,也不是冪等的,如果常見的POST重復(fù)加載的問題,我們進(jìn)行了多少次POST的操作,最后就創(chuàng)建了多少個資源,這也是為什么Chrom等瀏覽器,在刷新POST請求時會有彈窗提示

所以,你使用PUT上傳,是沒有問題,使用POST上傳也是可以。
但是,你使用PUT上傳的時候,需要后端處理 數(shù)據(jù),把相應(yīng)的 header 頭數(shù)據(jù),名字、大小等獲取到,再保存寫入文件就可以。

前端代碼,這樣處理數(shù)據(jù)沒有問題,后端處理如下(以PHP為例子)

public function getPut(string! name = null, var filters = null, var defaultValue = null, boolean notAllowEmpty = false, boolean noRecursive = false) -> var
{
    var put;

    let put = this->_putCache;

    if typeof put != "array" {
        let put = [];
        parse_str(this->getRawBody(), put);

        let this->_putCache = put;
    }

    return this->getHelper(put, name, filters, defaultValue, notAllowEmpty, noRecursive);
}


public function getRawBody() -> string
{
    var rawBody, contents;

    let rawBody = this->_rawBody;
    if empty rawBody {

        let contents = file_get_contents("php://input");

        /**
         * We need store the read raw body because it can't be read again
         */
        let this->_rawBody = contents;
        return contents;
    }
    return rawBody;
}

這個就是put的處理方式 contents = file_get_contents("php://input");

2018年4月30日 07:14