You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用cordova-plugin-file上传cdvfile://路径文件至服务器

无cordova-plugin-file-transfer的上传实现方案

你当前安装的3个插件已经完全满足上传需求,直接用浏览器标准API即可完成带自定义参数的文件上传,无需额外安装插件。

前置配置确认

先检查项目根目录的config.xml,确保有以下配置,避免请求被拦截:

  • 添加上传目标服务器的访问白名单:<access origin="https://你的上传接口域名" />
  • 如果是Android 10+版本,在<platform name="android">节点下加上<preference name="AndroidInsecureFileModeEnabled" value="true" />,避免本地文件读取权限问题
  • 页面的Content-Security-Policy规则里,允许向目标服务器发请求,不要把connect-src规则限制过严

核心实现逻辑

你现在已经拿到了图片对应的FileEntry对象(就是resolveLocalFileSystemURL回调里的entry参数),只需要三步就能完成上传:

  1. 调用FileEntry的标准file()方法,拿到原生File对象
  2. 构造FormData实例,先追加所有需要的自定义参数,再追加图片文件
  3. 用XMLHttpRequest发POST请求到上传接口,和普通Web端FormData上传逻辑完全一致

可直接复用的代码

把你原来的onPhotoDataSuccess回调调整为以下写法,直接把上传逻辑绑定到Save按钮上即可:

function onPhotoDataSuccess(imageData) {
  plugins.crop.promise(imageData).then(function success (imageFinal) {
    resolveLocalFileSystemURL(imageFinal, function(entry) {
      // 原有预览逻辑保留
      $("#picPreviewBox").html('<img src="'+entry.toInternalURL()+'" width="100%" />');
      var buttonHtml = '<div class="btn btn-dark btn-sm" id="savePhotoBtn">Save</div> <div class="btn btn-dark btn-sm" id="discardPhotoBtn">discard</div>';
      $("#buttons_save_discard").html(buttonHtml);

      // 绑定保存上传事件
      $("#savePhotoBtn").off("click").on("click", function() {
        // 从FileEntry读取原生File对象
        entry.file(function(fileObj) {
          // 构造上传表单
          const uploadForm = new FormData();
          // 按需追加自定义参数,比如用户ID、图片分类等
          uploadForm.append('userId', '当前登录用户ID');
          uploadForm.append('photoType', 'profile');
          // 追加图片文件,第三个参数为自定义文件名
          uploadForm.append('profilePhoto', fileObj, 'profile_' + Date.now() + '.jpg');

          // 初始化上传请求
          const xhr = new XMLHttpRequest();
          // 替换为实际的上传接口地址
          xhr.open('POST', 'https://你的上传接口地址');
          
          // 如需监听上传进度可开启以下回调
          xhr.upload.onprogress = function(e) {
            if (e.lengthComputable) {
              const uploadPercent = (e.loaded / e.total * 100).toFixed(0);
              console.log('上传进度:' + uploadPercent + '%');
            }
          };

          xhr.onload = function() {
            if (xhr.status === 200) {
              // 上传成功,处理接口返回结果
              const res = JSON.parse(xhr.responseText);
              console.log('上传成功', res);
              $.alert('头像保存成功');
            } else {
              $.alert('上传失败,错误码:' + xhr.status);
            }
          };

          xhr.onerror = function() {
            $.alert('网络异常,上传失败');
          };

          // 发送表单数据
          xhr.send(uploadForm);
        }, function(err) {
          $.alert('读取本地图片失败,请重试');
          console.error('读取文件错误', err);
        });
      });

      // 丢弃按钮逻辑
      $("#discardPhotoBtn").off("click").on("click", function() {
        $("#picPreviewBox").empty();
        $("#buttons_save_discard").empty();
      });
    });
  }).catch(function fail (err) {
    $.alert("Seems your phone resources are too low to proceed further");
  });
}

注意事项

  • 不要用fetch发送该上传请求,部分低版本Cordova WebView中fetch对本地File对象的序列化存在兼容问题,XMLHttpRequest全版本兼容,稳定性更高
  • 后端接收该请求的逻辑和接收普通Web端表单文件上传的逻辑完全一致,不需要做特殊适配
  • 如需传递更多参数,直接通过uploadForm.append()追加即可,和普通表单传参没有区别
  • 原代码中定义的未使用的fileURI变量可以直接删除,不影响功能运行

内容的提问来源于stack exchange,提问作者Riya Singh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 14:48:17