简体   繁体   English

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

[英]Angularjs file upload in put method not working

I have a simple todos application in which i am trying to upload a photo along with a single todo. 我有一个简单的待办事项应用程序,我试图上传一张照片和一个待办事项。 Now i have created this factory function that takes care of the creation of the todo 现在我已经创建了这个工厂函数来处理todo的创建

  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;
      }
    });
  };

And the factory update method looks like this 工厂更新方法如下所示

  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;
      }
    });
  };

The insertTodo is working as expected but the updateTodo is not posting data to the server. insertTodo按预期工作,但updateTodo未将数据发布到服务器。 I am using laravel for the API and the update API endpoint has this code 我正在使用laravel作为API,更新API端点具有此代码

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

This shows that noting was posted in the request. 这表明注释已在请求中发布。 And if i change the put to post in the updateTodo factory method it starts working. 如果我在updateTodo工厂方法中将put更改为post,它将开始工作。 Am i missing some extra headers or something ? 我错过了一些额外的标题或什么?

Update 更新

If i remove both the transformRequest and headers form the updateTodo method, the text data is successfully received on the server but the the file doesn't. 如果我从updateTodo方法中删除transformRequestheaders ,则在服务器上成功接收文本数据,但文件数据没有。
And if i just remove the headers nothing gets posted 如果我只是删除headers没有发布

Update 更新

I am using the PHP server that comes with laravel using this command 我正在使用laravel附带的PHP服务器使用此命令

php artisan serve

Update 更新

Thanks to @Ricardo's answer i was able to get the submitted data using this code 感谢@ Ricardo的回答,我能够使用此代码获取提交的数据

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

I am getting the stream in this format 我正在以这种格式获取流

-----------------------------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�

Now i need to parse this raw format. 现在我需要解析这种原始格式。 I have found two php methods that other people have suggested http://php.net/manual/en/function.mb-parse-str.php and http://php.net/manual/en/function.parse-str.php but both of them are not working properly and do not give an array like $_GET or $_POST. 我找到了其他人建议的两种php方法http://php.net/manual/en/function.mb-parse-str.phphttp://php.net/manual/en/function.parse-str .php但是它们都没有正常工作,也没有给出像$ _GET或$ _POST这样的数组。

This piece from the PHP documentation discusses the PUT method and file uploads (multipart/form-data). PHP文档中的这篇文章讨论了PUT方法和文件上传(multipart / form-data)。

I can't quote any parts from it because I think everything is important. 我不能引用它的任何部分因为我认为一切都很重要。 You should read it in detail but to summarize it's not possible without changes to your Apache configuration and creation of auxiliary scripts. 您应该详细阅读它,但总结一下,如果不更改Apache配置和创建辅助脚本,这是不可能的。

With Laravel you should use Form Method Spoofing (basically a variable called _method ) and keep on using POST. 使用Laravel,您应该使用Form Method Spoofing (基本上是一个名为_method的变量)并继续使用POST。 The _method will allow you to call Laravel's PUT action correctly. _method将允许您正确调用Laravel的PUT操作。


Edit 编辑

AngularJS, by default, sends data in the JSON format which explains why you cannot access the data with the $_POST global. 默认情况下,AngularJS以JSON格式发送数据,这解释了为什么您无法使用$_POST全局访问数据。 I have answered this in another question which explains what you have to do. 我在另一个问题中回答了这个问题 ,这个问题解释了你要做什么。

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

Create you formData upfront -> you don't need the transformer for that. 事先创建formData - >你不需要变换器。
Add transformRequest : angular.identity to your HTTP headers. transformRequest : angular.identity添加到HTTP标头中。 Your code should look similar to the snippet below: 您的代码应类似于以下代码段:

$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 identity does nothing more than to spit back your form data: https://docs.angularjs.org/api/ng/function/angular.identity 角度身份只不过是吐出你的表单数据: https//docs.angularjs.org/api/ng/function/angular.identity

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM