【问题标题】:Send Locally Stored Image to Server Via Ajax通过 Ajax 将本地存储的图像发送到服务器
【发布时间】:2014-01-03 05:55:49
【问题描述】:

为了这个问题的直截了当的答案,我一直在寻找高低。

我在以下目录的电话间隙应用程序中本地加载了一张图片:

/image/test.png

我想将此图像作为使用表单数据的多部分表单的一部分发送到服务器。

var formdata = new FormData();

然后我附加我的 JSON

formdata.append("json", JSON.stringify(request));

然后我想附加图像并尝试使用以下内容

var img = new Image();
img.src = './image/test.png';

formdata.append("file", img.src );

$.ajax(
{
  url : "http://myserver:8080/myservlet",
  type : "POST",
  data : formdata,
  processData : false,
  contentType : false,
  dataType : "json",
  success : function(response)
  {
    console.log("success response:"+JSON.stringify(response));
  },
  error : function(jqXHR,textStatus,errorThrown)
  {
    var msg = "Error Sending File. Status: "+textStatus+" Error:"+errorThrown;
    navigator.notification.alert(msg, null, "Error", "OK");
  }
});

如果课程对我不起作用 - 我做错了什么。

【问题讨论】:

    标签: javascript ajax json html cordova


    【解决方案1】:

    在 phonegap 上,您可以使用 FileTransfer 插件。在发布 PhoneGap 3 时,您必须在 config.xml 中包含该插件

     <gap:plugin name="org.apache.cordova.file" />
     <gap:plugin name="org.apache.cordova.file-transfer" />
    

    然后上传到服务器做这样的事情:

      var imageUploadSuccess = function (data) {
            alert("Cool");
      }
      var imageUploadFail = function (error) {
        alert("fail");
      }
    
      var params = new Object();
      params.yourHttpParam = "My Param Value";
      var url ="http://myserver.com/photo/upload";
    
      var options = new FileUploadOptions();
      options.fileName = "/image/test.png";
      options.mimeType = "image/png";
      options.fileKey = "file";
      options.params = params;
      options.chunkedMode = false;
      var ft = new FileTransfer();
      ft.upload("/image/test.png", url, imageUploadSuccess, imageUploadFail, options, true);
    

    【讨论】:

    • 请注意,如果您从相机/imageURI 上传,请使用:imageURI.substr(imageURI.lastIndexOf('/')+1) 获取文件名。
    • 谢谢让我检查一下将其他项目作为参数发送,我假设这在幕后使用 POST 和表单数据类型传输。
    • 这是一个帖子,文件将是一个 Miltipart 文件,但是您在服务器上实现它
    【解决方案2】:

    您需要使用FileTransfer API,注意在撰写本文时它存在一些问题(however they are being addressed.)。

    有关详细信息,请参阅此处的文档。 http://docs.phonegap.com/en/3.2.0/cordova_file_file.md.html#FileTransfer

    这是一个简单的例子:

    var fileURI = // imageURI returned by the CameraAPI.
    
    var success = function (r) {
        console.log("Code = " + r.responseCode);
        console.log("Response = " + r.response);
        console.log("Sent = " + r.bytesSent);
    }
    
    var fail = function (error) {
        alert("An error has occurred: Code = " + error.code);
        console.log("upload error source " + error.source);
        console.log("upload error target " + error.target);
    }
    
    var options = new FileUploadOptions();
    options.fileKey = "file";
    options.fileName = fileURI.substr(fileURI.lastIndexOf('/') + 1);
    options.mimeType = "text/plain";
    
    // The following options are to attempt circumvention of the
    // FileTransfer.upload issues in the linked Cordova thread.
    // Note that they are reportedly, not always effective.
    options.headers={Connection: "close"};
    options.chunkedMode = false;
    
    var params = {};
    params.value1 = "test";
    params.value2 = "param";
    
    options.params = params;
    
    var ft = new FileTransfer();
    ft.upload(fileURI, encodeURI("http://some.server.com/upload.php"), success, fail, options);
    

    您需要在 Android Manifest 中启用文件和文件传输插件。

    <gap:plugin name="org.apache.cordova.file" />
    <gap:plugin name="org.apache.cordova.file-transfer" />
    

    关于已知问题的快速说明...上传将在所有其他后续上传失败(即成功、失败、成功、失败等...) - 请注意,此问题有受影响的iOS和Android(我不能代表BB或其他平台。)AFAIK,Android仍然受到影响,但我建议你read the thread并密切关注它。

    有推荐的解决方案/解决方法,但也有报告称它们失败(即关闭分块模式并尝试强制关闭连接。)

    在有可靠的修复之前,最好只保留一个尝试连接计数器,并处理偶数失败作为立即重试的原因。 (讨厌,但必要。)

    【讨论】:

    • 我在 android 上传带有附加帖子数据的图像时没有问题。我正在使用我的答案中所述的上传选项。我根本没有上传错误...
    • 正如我所说,请参阅上面链接的线程。当然,它似乎不会影响每台设备,但正如您所读到的,它已被广泛报道。
    • @kasperTaeymans 在某些情况下, close / chunked 解决了问题,但在其他情况下,不是。 - 仅供参考,我会将Connection: close 添加到我的示例中。
    【解决方案3】:

    您正在尝试上传图像(=文件),但实际上您正在发布由img.src 返回的字符串。如果您想发布您的图片,您需要将其转换为可以发布的字符串。您可以通过将图像加载到画布元素中并拨打电话toDataUrl 来做到这一点。但是,当使用 phonegap 时,我建议通过文件传输上传文件并将您的其他帖子数据添加到其中...

    function uploadPhoto(imageUrlToUpload) {
        //alert('upload: '+imageUriToUpload);
        var url=encodeURI(youruploadurl);
        var params = new Object();
        params.your_param_name = "something";  //add your additional post parameters here
        var options = new FileUploadOptions();
        options.headers={Connection: "close"};
        options.fileKey = "file"; //depends on the api
        options.fileName = imageUriToUpload.substr(imageUriToUpload.lastIndexOf('/')+1);
        options.mimeType = "image/jpeg";
        options.chunkedMode = false; //this is important to send both data and files
        options.params = params;
    
        var ft = new FileTransfer();
        //what to do during the file transfer? lets show some percentage...
        var status=$('yourselectorhere');//element in the dom that gets updated during the onprogress
        ft.onprogress = function(progressEvent) {
            var perc;
    
            if (progressEvent.lengthComputable) {
    
    
                    perc = Math.ceil(progressEvent.loaded / progressEvent.total * 100);
    
                    status.html(perc+'%'+ '('+progressEvent.total+')');
    
            }else{alert('not computable');}
        };
    
        ft.upload(imageUrlToUpload, url, success, fail, options);
    }
    
    function success(r) {
        alert("Upload success: Code = " + r.responseCode);
    }
    
    function fail(error) {
        alert("An error has occurred: Code = " + error.code);
    }
    

    【讨论】:

    • 在传递附加参数时 - 我试图找到与表单数据平行的,所以我假设我有一个名称和一个值参数。那么 formdata.append("name", "value" 是否等于 params.name = "value"?这基本上是一个多/部分 POST 吗?
    【解决方案4】:

    您可以使用plugin 获取本地图像的 base64 编码,然后使用 ajax 将其发送到服务器:

    window.plugins.Base64.encodeFile(filePath, function(base64){
            console.log('file base64 encoding: ' + base64);
            //write down ajax code to send base64 string
        });
    

    【讨论】:

    • 然后你必须使用 javascript async 或 promise 获取所有文件的所有 base64,然后将整个数组发送到服务器
    • 你好哈泽姆。我看到的问题是,当调用函数(base64)时,我不知道哪个文件已被编码(我认为 filePath 不可用),因此我无法将其设置为 例如。希望我错了。
    猜你喜欢
    • 1970-01-01
    • 2018-02-27
    • 2016-09-02
    • 2021-03-05
    • 2020-04-16
    • 1970-01-01
    • 2011-07-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多