请问上传文件如何使用put形式上传。我写了一个demo,但是后台接收的一直是空。

是我这个put形式传递的参数有问题吗?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)
                    // 根据返回结果指定界面操作
            }
        });
    })
</script>
</html>
阅读 6.7k
1 个回答

首先,先解析一下 POSTPUT 的区别

HTTP/1.1协议中共定义了8中请求方法:GET、HEAD、POST、PUT、DELETE、CONNECT、OPTIONS、TRACE,其中用的相对较多的有下面四种:

GET      获取资源
PUT      更新或创建资源
POST     创建资源
DELETE   删除资源

RESTful api则充分利用了HTTP协议,每个资源对应一个具体的URI,然后利用不同的HTTP操作对应增删改查,如:

POST       /uri       创建
DELETE     /uri/xxx   删除
PUT        /uri/xxx   更新或创建
GET        /uri/xxx   查看

可以看到,GET和DELETE对应的操作非常明确,但是POST与PUT都可以进行资源的创建,那么什么时候用POST什么时候用PUT呢

这就需要了解HTTP协议中的另一个重要性质:幂等

什么是幂等

要理解PUT和POST的区别,还要知道HTTP协议中的一个重要性质,幂等(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协议中的幂等指的是一个资源无论请求多少次,对他产生的副作用是一样的

GET操作是安全的,也就是不管操作多少次,资源的状态都不会改变,所以GET也是幂等的
PUT和DELETE是幂等的,比如我用PUT或者DELETE修改一个资源,不管操作多少次,每次操作后的结果并没有什么不同
POST操作既不是安全的,也不是幂等的,如果常见的POST重复加载的问题,我们进行了多少次POST的操作,最后就创建了多少个资源,这也是为什么Chrom等浏览器,在刷新POST请求时会有弹窗提示

所以,你使用PUT上传,是没有问题,使用POST上传也是可以。
但是,你使用PUT上传的时候,需要后端处理 数据,把相应的 header 头数据,名字、大小等获取到,再保存写入文件就可以。

前端代码,这样处理数据没有问题,后端处理如下(以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");

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题