使用AngularJS上传文件失败

时间:2014-08-29 02:55:02

标签: python angularjs file-upload flask

以下是我的代码有关文件上传的摘要。

这是我的HTML代码,我将选择并上传文件:

<form ng-click="addImportFile()" enctype="multipart/form-data">
    <label for="importfile">Import Time Events File:</label><br><br>
    <label for="select_import_file">SELECT FILE:</label><br>
    <input id="import_file" type="file" class="file btn btn-default" ng-disabled="CutOffListTemp.id== Null" data-show-preview="false">
    <input class="btn btn-primary" type="submit" name="submit" value="Upload" ng-disabled="CutOffListTemp.id== Null"/><br/><br/>
</form>

这是我的控制器,它将链接html和我的python文件:

angular.module('hrisWebappApp').controller('ImportPayrollCtrl', function ($scope, $state, $stateParams, $http, ngTableParams, $modal, $filter) {
  $scope.addImportFile = function() {
    $http.post('http://127.0.0.1:5000/api/v1.0/upload_file/' + $scope.CutOffListTemp.id, {})
    .success(function(data, status, headers, config) {
      console.log(data);

      if (data.success) {
        console.log('import success!');
      } else {
        console.log('importing of file failed' );
      }
    })
    .error(function(data, status, headers, config) {});
};

这是我的python文件:

@api.route('/upload_file/<int:id>', methods=['GET','POST'])
@cross_origin(headers=['Content-Type'])
def upload_file(id):
    print "hello"
    try:
        os.stat('UPLOAD_FOLDER')
    except:
        os.mkdir('UPLOAD_FOLDER')
    file = request.files['file']
    print 'filename: ' + file.filename

    if file and allowed_file(file.filename):
        print 'allowing file'
        filename = secure_filename(file.filename)
        path=(os.path.join(current_app.config['UPLOAD_FOLDER'], filename))
        file.save(path) #The end of the line which save the file you uploaded.
        return redirect(url_for('uploaded_file',
                                            filename=filename))
    return '''
        <!doctype html>
        <title>Upload new File</title>
        <h1>Upload new File</h1>
        <p>opsss it seems you uploaded an invalid filename please use .csv only</p>

        <form action="" method=post enctype=multipart/form-data>
          <p><input type=file name=file>
             <input type=submit value=Upload>
        </form>
        '''

即使我选择了正确的文件格式,控制台中的结果也给了我这个:

<!doctype html>
<title>Upload new File</title>
<h1>Upload new File</h1>
<p>opsss it seems you uploaded an invalid filename please use .csv only</p>
<form action="" method=post enctype=multipart/form-data>
<p><input type=file name=file>
<input type=submit value=Upload>
</form>

这不会返回我的HTML而我无法上传文件。

2 个答案:

答案 0 :(得分:3)

嗨我终于可以上传文件了,我改变了角度部分,我改变了它:

    $scope.addImportFile = function() {
     var f = document.getElementById('file').files[0]; console.log(f);
     var formData = new FormData();
     formData.append('file', f);
                        $http({method: 'POST', url: 'http://127.0.0.1:5000/api/v1.0/upload_file/' +$scope.CutOffListTemp.id,
                         data: formData,
                         headers: {'Content-Type': undefined},
                         transformRequest: angular.identity})
                        .success(function(data, status, headers, config) {console.log(data);
                        if (data.success) {
                            console.log('import success!');

                        }
                    })
                    .error(function(data, status, headers, config) {
                    });
            // }
        };

答案 1 :(得分:1)

首先是关于帖子请求。如果没有ng-click =&#34; addImportFile()&#34;,浏览器通常会负责序列化表单数据并将其发送到服务器。所以,如果你尝试:

<form method="put" enctype="multipart/form-data" action="http://127.0.0.1:5000/api/v1.0/upload_file">
    <label for="importfile">Import Time Events File:</label><br><br>
    <label for="select_import_file">SELECT FILE:</label><br>
    <input id="import_file" type="file" name="file" class="file btn btn-default" ng-disabled="CutOffListTemp.id== Null" data-show-preview="false">
    <input class="btn btn-primary" type="submit" name="submit" value="Upload" ng-disabled="CutOffListTemp.id== Null"/><br/><br/>
</form>

然后在python中,使你的请求url独立于scope.CutOffListTemp.id: @ api.route(&#39; / upload_file&#39;,methods = [&#39; GET&#39;,&#39; POST&#39;])

它可能会奏效。

或者,如果您想使用自定义函数发送帖子请求,浏览器将不再处理序列化内容,您需要自己完成。

在angular中,$ http.post的API是: $ http.post(&#39; / someUrl&#39;,data).success(successCallback); 如果我们使用&#34; {}&#34;对于data参数,这意味着为空,服务器将找不到名为&#34; file&#34;的数据。 (file = request.files [&#39; file&#39;])。因此,您将看到错误的请求

要解决此问题,我们需要使用formData进行文件上传,这需要您的浏览器支持HTML5:

$scope.addImportFile = function() {
    var f = document.getElementById('file').files[0]
    var fd = new FormData();
    fd.append("file", f);

    $http.post('http://127.0.0.1:5000/api/v1.0/upload_file/'+$scope.CutOffListTemp.id,
               fd,
               headers: {'Content-Type': undefined})
    .success......

除了使用上面的原生javascript代码之外,还有很多很棒的角度文件上传库,可以让角度更容易上传文件,你可能想看看其中一个(参考:File Upload using AngularJS ):