请求的contentType需要multipart/form-data,怎么转换?

请求时根据控制台来看,contentType是text/plain,而我需要multipart/form-data类型
请问怎么转换呢?

图片描述

html:

<form ng-submit="processForm()" enctype="multipart/form-data">
    <div class="form-group">
        <label class="label"><span class="tip" ng-hide="data.id">*</span>ID:</label>
        <input class="input" name="id" ng-model="data.id" maxlength="5">
    </div>
    <div class="form-group">
        <input type="file" name="preview" fileread="data.preview"><!--改动在这里-->
    </div>
    <button type="submit" class="btn btn-default btn-small">保存</button>
</form>

js:

$scope.processForm = function(){
        var data = $scope.data,
            url = Api.add,
            config;
        $http({
            method: 'POST',
            url: url,
            data: data,
            headers: {'Content-Type': undefined},
         }).then(function(result){
.directive("fileread", [function () {
    return {
        scope: {
            fileread: "="
        },
        link: function (scope, element, attributes) {
            element.bind("change", function (changeEvent) {
                var reader = new FileReader();
                reader.onload = function (loadEvent) {
                    scope.$apply(function () {
                        scope.fileread = loadEvent.target.result;
                    });
                }
                reader.readAsDataURL(changeEvent.target.files[0]);
            });
        }
    }
}]);
阅读 9.1k
4 个回答

找到解决方法了
http://blog.csdn.net/wei38908...
https://github.com/ghostbar/a...

html

<form enctype="multipart/form-data">
    <div class="form-group">
        <label class="label"><span class="tip" ng-hide="data.id">*</span>ID:</label>
        <input class="input" name="id" ng-model="data.id" maxlength="5">
    </div>
    <div class="form-group">
        <input type="file" name="preview" file-model='fileModel'>
    </div>
    <button type="submit" class="btn btn-default btn-small" ng-click="save()">保存</button>
</form>

弃用了题目里的directive,改用链接里的angular-file-model

(function () {
  'use strict';

  angular.module('file-model', [])

  .directive('fileModel', [
    '$parse',
    function ($parse) {
      return {
        restrict: 'A',
        link: function(scope, element, attrs) {
          var model = $parse(attrs.fileModel);
          var modelSetter = model.assign;

          element.bind('change', function(){
            scope.$apply(function(){
              if (attrs.multiple) {
                modelSetter(scope, element[0].files);
              }
              else {
                modelSetter(scope, element[0].files[0]);
              }
            });
          });
        }
      };
    }
  ]);

})();

保存的方法:

$scope.save = function(){
        var data = new FormData(),
            file = document.querySelector('input[type=file]').files[0],
            url = Api.add,
            config;
            data.append('preview', file);
            data.append('id', $scope.data.id);
            $http({
                    method: 'POST',
                    url: url,
                    data: data,
                    headers: {'Content-Type': undefined},
                    transformRequest: angular.identity
                }).then(function(result){

但是没看懂解决方法里的代码……感觉自己照抄来的也很粗糙……抛砖引玉……

评论里大佬说要用ajax只有通过FormData提交……原来是这个原因啊……头大
https://developer.mozilla.org...

图片描述

$http({
    method: 'POST',
    url: url,
    data: data,
    headers: {'Content-Type': undefined},
 }).then(function(result){

你把这个headers指定删掉,或者改为headers: {'Content-Type': 'multipart/form-data'}估计就行了

buildParam() {
    var contentType = this.contentType;

    // 上传文件表单等FormData格式
    if (contentType === false) {
        return this.params.body;
    }

    // 其他格式
    if (contentType != 'application/json') {
        return this.params;
    }

    //商控默认json格式
    return JSON.stringify(this.params);
}

execute(onComplete, onError, context) {
    var self = this;

    onComplete = onComplete || $.noop;
    onError = onError || $.noop;
    context = context || this;

    var opt = {
        url: this.buildUrl(this.url),
        type: this.type || 'POST',
        dataType: this.datatype || 'json',
        contentType: (function(context){
            var contentType = self.contentType;
            if (contentType === false) {
                return contentType;
            }
            return contentType || 'application/json';
        })(this),
        processData: this.contentType === false ? false : true,
        data: this.buildParam(),
        timeout: this.timeout,
        crossDomain: false,
        success: function (res, status, xhr) {
            if ((res && res.errNo == 0) && (xhr && xhr.status == 200)) {
                onComplete.apply(context, arguments);
            } else {
                onError.apply(context, arguments);
            }
        },
        error: function (err, status) {
            onError.apply(context, arguments);
        }
    };

    if (opt.url.indexOf(window.location.host) === -1 || opt.url.indexOf(window.location.protocol) === -1) {
        opt.crossDomain = true;
    }

    // 设置token
    const userInfo = Session.getInstance().getItem(CONSTANTS.SESSION_KEY_USERINFO);
    if (userInfo && userInfo.token) {
        if (opt.headers) {
            opt.headers.Authorization = userInfo.token;
        } else {
            opt.headers = { Authorization: userInfo.token };
        }
    }

    this.ajaxRequest = this.sendReq(opt);
}

sendReq(opt) {
    return $.ajax(opt);
}

//REACT UNMOUNT大概需要
abort() {
    if (this.ajaxRequest && this.ajaxRequest.abort) {
        this.ajaxRequest.abort();
    }
}

我自己项目里封装的 可以参考下 大概原理就是data传formdata类型contentType和processData传false 浏览器会自动识别

设置{'Content-Type': undefined}让浏览器自动识别content类型后,还需要覆盖$httptransformRequest默认预处理逻辑(默认的处理逻辑好像是转换为JSON format),比如

$http({
...
transformRequest: angular.identity
...
})

试试吧,不一定好使

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