3

使用使用 build.phonegap.com 构建的应用程序我发现 FileUploadOptions.params 值没有被发布 - iOS(8.4.1)只发布文件多部分数据。这不是服务器端错误,因为我使用 tcpdump/Wireshark 和 netcat 观看了 POST。

使用:

  • PhoneGap v.3.7.0
  • 离子框架 v.1.0.1
  • AngularJS v.1.3.13

这是用于上传测试文件的代码。它会生成一个临时文件并尝试上传它。问题是,我是不是搞砸了什么,或者这是一个真正的错误?

  $scope.doUploadTest = function() {
    var q = $q.defer();
    var promise = q.promise;

    var text = "Test file content: " + new Date();

    $window.requestFileSystem(LocalFileSystem.TEMPORARY, text.length, function(fs) {
      q.resolve(fs);
    }, function(err) {
      q.reject(err);
    });

    promise
    .then(function(fs) {
      var qFile = $q.defer();

      fs.root.getFile("upload.tmp", {create: true, exclusive: false}, function(entry) {
        qFile.resolve(entry);
      }, function(err) {
        qFile.reject(err);
      });

      return qFile.promise;
    })
    .then(function(entry) {
      console.log("got file: " + entry.nativeURL);

      var qWriter = $q.defer();

      entry.createWriter(function(writer) {
        qWriter.resolve({writer: writer, entry: entry});
      }, function(err) {
        qWriter.reject(err);
      });

      return qWriter.promise;
    })
    .then(function(response) {
      var qWrite = $q.defer();

      response.writer.onwriteend = function(evt) {
        qWrite.resolve(response.entry);
      };

      response.writer.write(text);

      return qWrite.promise;
    })
    .then(function(entry) {
      $scope.error = entry;

      var qUpload = $q.defer();

      var options = new FileUploadOptions();
      options.params = {
        Value: {
          list: [1, 2, 3],
          text: "foo bar baz",
          number: 1234
        }
      };
      options.fileKey = "thefile";
      options.fileName = entry.name;
      options.mimeType = "text/plain";
      options.chunkedMode = false;
      options.headers = {
        "X-Upload": (new Date()).toString()
      };


      var ft = new FileTransfer();
      ft.upload(entry.nativeURL, "http://192.168.0.30:9100/", function(success) {
        entry.remove();
        qUpload.resolve(success);
      }, function(err) {
        entry.remove();
        qUpload.reject(err);
      }, options);

      // Abort after 3 seconds
      $timeout(function() {
        console.log("Aborting upload - timed out");
        ft.abort();
      }, 3000);

      return qUpload.promise;
    })
    .then(function(response) {
      console.log("Upload succeeded");
      $scope.error = response;
    })

    .catch(function(err) {
      console.log("Upload failed");
      $scope.error = err;
    });
    ;


  };

在 iPhone 6 (iOS v.8.4.1) 上发出的请求如下:

    发布/HTTP/1.1
    主机:192.168.0.30:9100
    内容类型:multipart/form-data;边界=+++++org.apache.cordova.formBoundary
    接受编码:gzip,放气
    X-上传:2015 年 9 月 1 日星期二 12:12:49 GMT+0100 (BST)
    连接:保持活动
    接受: */*
    用户代理:Mozilla/5.0(iPhone;CPU iPhone OS 8_4_1,如 Mac OS X)AppleWebKit/600.1.4(KHTML,如 Gecko)Mobile/12H321(5348809648)
    内容长度:261
    接受语言:en-us
    X-Requested-With: XMLHttpRequest

    --+++++org.apache.cordova.formBoundary
    内容处置:表单数据;名称="文件"; 文件名="上传.tmp"
    内容类型:文本/纯文本
    内容长度:58

    测试文件内容:Tue Sep 01 2015 12:12:49 GMT+0100 (BST)
    --+++++org.apache.cordova.formBoundary--

在摩托罗拉 Moto X(第 2 代,Android 5.1)上,请求是这样的:

    发布/HTTP/1.1
    内容类型:multipart/form-data;边界=+++++
    X-上传:2015 年 9 月 1 日星期二 12:52:24 GMT+0100 (BST)
    用户代理:Dalvik/2.1.0(Linux;U;Android 5.1;XT1092 Build/LPE23.32-25.1)
    主机:192.168.0.30:9100
    连接:保持活动
    接受编码:gzip
    内容长度:289

    --+++++
    内容处置:表单数据;名称=“值”

    {"list":[1,2,3],"text":"foo bar baz","number":1234}
    --+++++
    内容处置:表单数据;名称="文件"; 文件名="上传.tmp"
    内容类型:文本/纯文本

    测试文件内容:Tue Sep 01 2015 12:52:23 GMT+0100 (BST)
    --+++++--

4

1 回答 1

0

事实证明, params 对象只能包含文字属性,而不能包含 objects。该文档仅使用字符串值,但没有明确说明对象不受支持。

由于在 Android 上插件将对象序列化为 JSON 字符串,而在 iOS 上插件静默转储它,这使情况变得更加复杂。

所以,解决方案就是先序列化数据:

  var options = new FileUploadOptions();
  options.params = {
    Value: JSON.stringify({
      list: [1, 2, 3],
      text: "foo bar baz",
      number: 1234
    })
  };
于 2015-09-03T15:03:53.423 回答