当前位置: 首页 > 知识库问答 >
问题:

在AJAX POST请求中通过JS发送图像

岳阳飙
2023-03-14

我是一名服务器端开发人员,学习vanilla JS的诀窍。我需要澄清我的概念,即为我在JS中创建的图像对象发送Ajax POST请求——这个问题与此有关。

想象一下一个网络应用,用户上传照片供他人查看。在上传每个图像时,我使用vanilla JS确认图像的mime类型(通过解释幻数),然后调整图像大小以达到优化目的。

调整大小后,我会:

    var canvas = document.createElement('canvas');
    canvas.width = resized_width;
    canvas.height = resized_height;
    var ctx = canvas.getContext("2d");
    ctx.drawImage(source_img, 0, 0, resized_width, resized_height);
    var resized_img = new Image();
    resized_img.src = canvas.toDataURL("image/jpeg",0.7);
    return resized_img;

返回的图像对象必须通过Ajax请求发送到后端。比如:

function overwrite_default_submit(e) {
  e.preventDefault();
  var form = new FormData();
  form.append("myfile", resized_img, img_name);
  var xhr = new XMLHttpRequest();
  xhr.open('POST', e.target.action);
//  xhr.send(form); // uncomment to really send the request
}

然而,调整大小后返回的图像对象本质上是一个HTML元素,如so

那么我该怎么解决这个问题呢?我更愿意在这里学习最有效的做事方式。

顺便说一句,我见过一个使用JS FILE对象的例子,但我更喜欢跨浏览器的方法,因为最近,FILE获得了Safari、Opera Mobile和内置Android浏览器的支持。

此外,只需要纯JS解决方案,因为我用它作为学习诀窍的练习。JQuery在我的雷达上,但以后会有。

我的其余代码如下(为了简洁起见,仅包括JPEG处理):

var max_img_width = 400;
var wranges = [max_img_width, Math.round(0.8*max_img_width), Math.round(0.6*max_img_width),Math.round(0.4*max_img_width),Math.round(0.2*max_img_width)];

// grab the file from the input and process it
function process_user_file(e) {
  var file = e.target.files[0];
  var reader = new FileReader();
  reader.onload = process_image;
  reader.readAsArrayBuffer(file.slice(0,25));
}

// checking file type programmatically (via magic numbers), getting dimensions and returning a compressed image
function process_image(e) {
  var img_width;
  var img_height;
  var view = new Uint8Array(e.target.result);
  var arr = view.subarray(0, 4);
  var header = "";
  for(var i = 0; i < arr.length; i++) {
     header += arr[i].toString(16);
  }
  switch (header) {
    case "ffd8ffe0":
    case "ffd8ffe1":
    case "ffd8ffe2":
    case "ffd8ffe3":
    case "ffd8ffe8":
        // magic numbers represent type = "image/jpeg";
        // use the 'slow' method to get the dimensions of the media
        img_file = browse_image_btn.files[0];
        var fr = new FileReader();
        fr.onload = function(){
          var dataURL = fr.result;
          var img = new Image();
          img.onload = function() {
              img_width = this.width;
              img_height = this.height;
              resized_img = resize_and_compress(this, img_width, img_height, 80);
            }
          img.src = dataURL;
        };
        fr.readAsDataURL(img_file);
        to_send = browse_image_btn.files[0];
        load_rest = true;
        subform.disabled = false;
        break;
    default:
        // type = "unknown"; // Or one can use the blob.type as fallback
        load_rest = false;
        subform.disabled = true;
        browse_image_btn.value = "";
        to_send = null;
        break;
    }
}

// resizing (& compressing) image
function resize_and_compress(source_img, img_width, img_height, quality){
    var new_width;
    switch (true) {
      case img_width < wranges[4]:
         new_width = wranges[4];
         break;
      case img_width < wranges[3]:
         new_width = wranges[4];
         break;
      case img_width < wranges[2]:
         new_width = wranges[3];
         break;
      case img_width < wranges[1]:
         new_width = wranges[2];
         break;
      case img_width < wranges[0]:
         new_width = wranges[1];
         break;
      default:
         new_width = wranges[0];
         break;
    }
    var wpercent = (new_width/img_width);
    var new_height = Math.round(img_height*wpercent);

    var canvas = document.createElement('canvas');
    canvas.width = new_width;
    canvas.height = new_height;
    var ctx = canvas.getContext("2d");
    ctx.drawImage(source_img, 0, 0, new_width, new_height);
    console.log(ctx);
    var resized_img = new Image();
    resized_img.src = canvas.toDataURL("image/jpeg",quality/100);
    return resized_img;
}

更新:我雇佣了以下人员:

// converting image data uri to a blob object
function dataURItoBlob(dataURI,mime_type) {
  var byteString = atob(dataURI.split(',')[1]);
  var ab = new ArrayBuffer(byteString.length);
  var ia = new Uint8Array(ab);
  for (var i = 0; i < byteString.length; i++) { ia[i] = byteString.charCodeAt(i); }
  return new Blob([ab], { type: mime_type });
}

其中dataURI参数为canvas.toDataURL(mime_type,质量/100)


共有2个答案

寿子默
2023-03-14

请参阅本文:如何从html图像中获取base64编码数据

我想你需要叫“画布”。toDataURL()'以获取图像的实际base64流。

var image = canvas.toDataURL();

然后用表单上传:用FormData上传base64编码的图像?

var data = new FormData();
data.append("image_data", image);

未经测试,但这应该是关于它。

郎鹤龄
2023-03-14

你应该给画布打电话。toBlob()获取二进制文件,而不是使用base64字符串。

它是异步的,所以您必须向它添加回调。

canvas.toBlob(function(blob) {
  resized_img.onload = function() {
    // no longer need to read the blob so it's revoked
    URL.revokeObjectURL(this.url);
  };

  // Preview the image using createObjectURL
  resized_img.src = URL.createObjectURL(blob);

  // Attach the blob to the FormData
  var form = new FormData();
  form.append("myfile", blob, img_name);
}, "image/jpeg", 0.7);
 类似资料:
  • 我如何发送此信息: 到API: 使用cURL,我目前一直在使用: 其中我得到了结果(NGrok): GET/testDir/curlPost。php HTTP/1.1 接受:text/html、Application/xhtml xml、image/jxr、/ 接受语言:en-GB 用户代理:Mozilla/5.0(Windows NT 10.0;Win64;x64)AppleWebKit/537

  • 我有一个restful请求,需要使用JMeter将其发送到webservice。以下是我的建议: 异常:服务器11.92.0.91在org.apache.commons.httpclient.httpmethodbase.readstatusline(httpmethodbase.java:1976)在org.apache.commons.httpclient.httpmethodbase.jav

  • 我正在尝试让客户端/服务器程序通过ssl交换http消息。首先,我创建了使用DefaultHttpRequest成功交换http请求的客户端和服务器程序。发送请求的代码如下所示: 客户端管道工厂包含以下内容: 服务器管道工厂包含以下内容: .... 到目前为止一切顺利。客户端发送请求,服务器接收并解码请求。使用正确的数据调用我的处理程序上的messageReceived方法。 为了启用 SSL,我

  • 问题内容: 我是Android的新手,所以关于android的知识还不是很多,好的,请讲到重点,我需要通过用户名和密码进行 登录 ,因为我必须通过JSON进行http requset并返回响应也将以JSON格式提供。所以任何人都可以帮助我。谢谢。 问题答案: 试试这个代码

  • 问题内容: 我已经设置好OkHttpClient并成功将GET请求发送到服务器。而且,我还可以将带有空body标签的POST请求发送到服务器。 现在,我正在尝试将以下JSON对象发送到服务器。 为此,我尝试添加OkHttpClient库类,但无法将JSON对象作为http POST请求的主体发送。我尝试通过以下方式构建主体并处理发布请求。 通过POST请求将JSON对象发送到服务器的方式是什么。

  • 我在烧瓶中设置了一个非常简单的帖子路线,如下所示: 这是我试图从命令行发送的curl请求: 但是,它仍然打印出“收到的数据:“无”。所以,它不识别我传递的JSON。 在这种情况下是否需要指定json格式?