在put方法中Angularjs文件上传不起作用

时间:2015-10-02 07:15:26

标签: javascript angularjs http laravel-5

我有一个简单的待办事项应用程序,我试图上传一张照片和一个待办事项。现在我创建了这个工厂函数,负责创建待办事项

  todosFactory.insertTodo = function(todo){
    return $http.post(baseUrl, todo, {
      headers: {
        'Content-Type' : undefined
      },
      transformRequest: function(data, headersGetter){
        var formData = new FormData();
        angular.forEach(data, function (value, key) {
            formData.append(key, value);
        });
        return formData;
      }
    });
  };

工厂更新方法如下所示

  todosFactory.updateTodo = function(id, todo){
    return $http.put(baseUrl + '/' + id, todo, {
      headers: {
        'Content-Type' : undefined
      },
      transformRequest: function(data, headersGetter){
        var formData = new FormData();
        angular.forEach(data, function (value, key) {
            formData.append(key, value);
        });
        return formData;
      }
    });
  };

insertTodo正在按预期工作,但updateTodo未将数据发布到服务器。我正在使用laravel作为API,更新API端点具有此代码

dd(Input::all(), Input::file('cover_photo'));

这表明注释已在请求中发布。如果我在updateTodo工厂方法中将put更改为post,它将开始工作。我错过了一些额外的标题或什么?

更新

如果我从updateTodo方法中删除了transformRequestheaders,则在服务器上成功接收到文本数据,但该文件没有。
如果我只是删除headers没有发布任何内容

更新

我正在使用laravel附带的PHP服务器使用此命令

php artisan serve

更新

感谢@ Ricardo的回答,我能够使用此代码获取提交的数据

router->put('/todos/{id}', function($id){
    $stream = file_get_contents("php://input");
    echo $stream;
    die();
});

我正在以这种格式获取流

-----------------------------3643739756006088191021064137
Content-Disposition: form-data; name="id"

5
-----------------------------3643739756006088191021064137
Content-Disposition: form-data; name="name"

Image Todo
-----------------------------3643739756006088191021064137
Content-Disposition: form-data; name="complete"

0
-----------------------------3643739756006088191021064137
Content-Disposition: form-data; name="created_at"

2015-10-02 06:28:10
-----------------------------3643739756006088191021064137
Content-Disposition: form-data; name="updated_at"

2015-10-02 06:28:10
-----------------------------3643739756006088191021064137
Content-Disposition: form-data; name="cover_photo"; filename="Dragon-Falls-Venezuela-5.jpg"
Content-Type: image/jpeg

�����JFIF��H�H������Exif��MM�*�����i������������������z���,����UNICODE��C�R�E�A�T�O�R�:� 
�g�d�-�j�p�e�g� �v�1�.�0� �(�u�s�i�n�g� �I�J�G� �J�P�E�G� �v�6�2�)�,� �q�u�a�l�i�t�y� �=� �9�0�

现在我需要解析这种原始格式。我找到了其他人提出的两种php方法http://php.net/manual/en/function.mb-parse-str.phphttp://php.net/manual/en/function.parse-str.php但是它们都没有正常工作,也没有给出像$ _GET或$ _POST这样的数组。

3 个答案:

答案 0 :(得分:1)

This piece from the PHP documentation讨论了PUT方法和文件上传(multipart / form-data)。

我无法引用它的任何部分,因为我认为一切都很重要。您应该详细阅读它,但总结一下,如果不更改Apache配置和创建辅助脚本,它是不可能的。

使用Laravel,你应该使用Form Method Spoofing(基本上是一个名为_method的变量)并继续使用POST。 _method将允许您正确调用Laravel的PUT操作。

修改

默认情况下,AngularJS以JSON格式发送数据,这解释了为什么您无法使用$_POST全局访问数据。我已经在another question中回答了这个问题,这解释了你必须做的事情。

答案 1 :(得分:0)

我认为您必须在服务器端序列化文件,如果您发送文件,则附加自定义标头并在服务器端适当处理该标头请求。

答案 2 :(得分:0)

预先创建formData - >你不需要变压器。
transformRequest : angular.identity添加到您的HTTP标题中。 您的代码应类似于以下代码段:

$http.post('/api/endpoint', formData, {
  transformRequest : angular.identity,
  headers: {'Content-Type': undefined}
})
.success(function (data) {
  // do stuff with data
})
.error(function (error) {
  // recover from an error
});

Angular身份只会吐出您的表单数据:https://docs.angularjs.org/api/ng/function/angular.identity