Is it possible to upload a jpeg file from a directory on my web server via Ajax? Currently the call that is created is receiving the jpeg from a form file upload using FormData(); .append('file', $('#imageFile')[0].files[0]);

I have the file on the server and would like to call that Ajax function via document ready or onLoad to prevent an extra step.

Here my current function:

    function uploadImage() {
        var formData = new FormData();
        formData.append('file', $('#imageFile')[0].files[0]);

    $.ajax({
        url: 'http://api.abcbiz.com/v1/graphics',
        headers: { Accept: 'application/json' },
        type: 'POST',
        data: formData,
        cache: false,
        contentType: false,
        processData: false,
        success: function(data) {
            var zpl = $('#zpl').val();
            var index = zpl.toUpperCase().indexOf('^XA');
            var cmd =
                  '\n'
                + '\n'
                + '^FO20,10^GFA,' + data.totalBytes + ',' + data.totalBytes + ',' + data.rowBytes + ',' + data.data + '^FS\n'
                + '\n'
                + '\n';
            if (index == -1) {
                zpl = cmd + zpl;
            } else {
                zpl = zpl.substring(0, index + 3) + cmd + zpl.substring(index + 3);
            }
            
            $('#sendZPL').val(zpl);
            $('#hiddenForm').stop(true,true).slideToggle(500);

            $('#zpl').val(zpl);
            refreshLabel();
            refreshPermalink();
        },
        error: function(jqxhr) {
            alert(jqxhr.responseText);
        }
    });
}

I also tried using cURL via PHP to bypass using the Ajax call but I kept getting a 'Unknown File Type" from the receiving server.

I appreciate any ideas. Thanks.

    Not sure what you're wanting: if it's already on your server why do you need to upload it?

      I am trying to access an outside API. It takes jpeg images and converts them to ZPL Code for printing on a Zebra label printers. Right now you have to access a form on their webpage and use that to do a file upload and it returns the ZPL Code. You can access the API via cURL they just don't document/support those type of request.

      I don't know how replicate this part doing a cURL request where the image is being uploaded from the actual web form:

      var formData = new FormData();
              formData.append('file', $('#imageFile')[0].files[0]);
      

      We create QR Codes on the fly via our site and those images reside on our server. I am not sure if there is a way to call that Ajax command and transfer the image directly from the our server w/o having to use the file upload on their site. Ideally after the QR Code jpg is generated > call their API > get the returned ZPL code > push straight to the printer with a socket_connect();

        Sounds like you're getting distracted by the "Ajax" bit and missing the point that it's just a form submission; in cURL you'd construct an array of the form fields (including the file) and their values and attach it using CURL_POSTFIELDS.

          Thanks for the reply. Here is what I've tried w/ cURL. The results I received are commented out after each $postData var. In this example I can use the same QR Code jpg and upload it via that Ajax request using a form and it will complete.

          I've also echo out <img src="$filePath"/> to make sure the image would display and that worked correctly.

          I also tried jpeg and a png with the same results. Works fine via the form but not w/ cURL.

          $url = 'http://api.abcbiz.com/v1/graphics';
          $ext = 'jpg';
          $name = 'zplQRCode';
          $fileName = $name.'.'.$ext;
          $filePath = $name.'.'.$ext;
          $mimeType = 'image/'.$ext;
          
          $cImg1 = curl_file_create($filePath, $mimeType, $fileName); 
          $cImg2 = new cURLFile($filePath, $mimeType, $fileName);
          
          //$postData = ['file' => $cImg1]; // bool(false);
          //$postData = ['file' => $cImg2]; // bool(false);
          $postData = ['file' => $filePath]; // ERROR: unknown image format
          
          //initialise cURL
          $ch = curl_init();
          
          curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
          curl_setopt($ch, CURLOPT_URL, $url);
          curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: multipart/form-data'));
          curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); 
          curl_setopt($ch, CURLOPT_POST, 1);
          curl_setopt($ch, CURLOPT_POSTFIELDS, $postData);
          curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
          
          //execute request
          $r = curl_exec($ch);
          var_dump($r);
          curl_close($r);
          

            $postData = ['file' => $filePath]; // ERROR: unknown image format according to the page for curl_setopt, $filePath here would start with '@' and be the full path to the file (you might also want to look at curl_setopt_array.) All this also critically depends on what version of PHP you're using.

            The service you're calling isn't going to know what you're using to generate the request, something about your cURL request isn't matching what you send when you use the form. Have you looked at the exact request you're making with the form to see if it matches? Do the referrer headers matter?
            I can't help you with what abcbiz.com is expecting, because all I can see of it is an empty domain registered with some Chinese company.

              I've tried the leading '@' in the image path and received the same result. (ERROR: Uknown.....)

              For some reason always change the actual URL's I am calling when posting. Actual URL:

              Web Service that the Form is calling:
              - http://api.labelary.com/v1/graphics'

              They have this in their FAQ's: (at very bottom)
              - http://labelary.com/faq.html#image-conversion

              This is the online viewer where grabbed that AJAX call:
              - http://labelary.com/viewer.html

              How would I got about seeing if the request match? Would I use Chrome Inspector?

                Chrome Inspector ... Firefox DevTools ... yes--that's the first step in understanding what the browser's doing.

                  Can't you send a cURL via Postman to see what's coming from the other end?

                    Are the files you're trying to upload contain ZPL strings? Because that's what the API you're using expects, and you're not doing anything in your code to encode your image files as ZPL (see the JavaScript you posted for what is involved there).

                      I see where the successful response data is being concatenated with ZPL code but I don't see where the image uploaded from the form is being encoded.

                      var formData = new FormData();
                              formData.append('file', $('#imageFile')[0].files[0]);
                        
                      $.ajax({ url: 'http://api.labelary.com/v1/graphics', headers: { Accept: 'application/json' }, type: 'POST', data: formData, cache: false, contentType: false, processData: false, success: function(data) { var zpl = $('#zpl').val(); var index = zpl.toUpperCase().indexOf('^XA'); var cmd = '\n' + '\n' + '^FO20,10^GFA,' + data.totalBytes + ',' + data.totalBytes + ',' + data.rowBytes + ',' + data.data + '^FS\n' + '\n' + '\n';

                      I also was attempting to match what the form is doing by using the inspector but I wasn't understanding what to really look for. I read a few tutorials but I don't know what to look for under the network tab. Can anyone point me in the right direction or suggest a decent Chrome Inspector tutorial? Thanks.

                        This is tying in quite close to my "Dropzone.js" issue.

                        Here's what I do in Firefox Dev tools, and Chrome would behave similarly.

                        1. Inspect any element on your page and then take the action that sends the XHR/Ajax.
                        2. Click the "Network" Tab/header link, and if desired (might be a good idea), click on "XHR".
                        3. You'll be looking in the left column for a POST to the labelary.com URL.
                        4. Click on that POST entry on the left. This will bring up the detailed request data in the right area.
                        5. Click on "Params" in the request details. Here you view what was sent by the browser. You should see a bunch of data, separated by lines of dashes most likely, much in the format of multi-part emails. Here's what an image might look like:
                        -----------------------------282442550224508
                        Content-Disposition: form-data; name="file0"; filename="Yellowstone.jpg"
                        Content-Type: image/jpeg
                        
                        ÿØÿá*¨Exif blahblahblahblahblahblahblah (there are binary/non-printable characters, but there are a boatload of them)

                        You should be able to see in the "headers" part of the request details what the content-type is being advertised as. It should most likely be "multipart/form-data" much like a MIME email (and I see that's what you're trying with cURL, so I think that's right).

                          When I run the following cURL page using FireFox:

                          $url = 'http://api.labelary.com/v1/graphics';
                          $ext = 'jpg';
                          $name = 'zplQRCode';
                          $fileName = $name.'.'.$ext;
                          $filePath = '@'.$name.'.'.$ext;
                          $mimeType = 'image/'.$ext;
                          
                          
                          $cImg1 = curl_file_create($filePath, $mimeType, 'bob'); 
                          $cImg2 = new CurlFile($filePath, $mimeType, $fileName);
                          
                          //$postData = ['file' => $cImg1]; // bool(false);
                          //$postData = ['file' => $cImg2]; // bool(false);
                          $postData = ['file' => $filePath]; // ERROR: unknown image format
                          
                          $header[] = "Accept:application/json"; 
                          $header[] = "Content-Type: multipart/form-data";
                          $header[] = "Cache-Control: max-age=0"; 
                          $header[] = "Connection: keep-alive"; 
                          $header[] = "Keep-Alive: 300"; 
                          $header[] = "Accept-Language: en-US,en;q=0.5"; 
                          
                          //initialise cURL
                          $ch = curl_init();
                          
                          $options =  [CURLOPT_RETURNTRANSFER => true,
                                       CURLOPT_URL => $url,
                                       CURLOPT_USERAGENT => 'Opera/9.80 (Windows NT 6.2; Win64; x64) Presto/2.12.388 Version/12.15)',
                                       CURLOPT_HTTPHEADER => $header,
                                       CURLOPT_SSL_VERIFYPEER => false,
                                       CURLOPT_POST => true,
                                       CURLOPT_POSTFIELDS => $postData,
                                       CURLOPT_FOLLOWLOCATION => true,
                                       CURLOPT_ENCODING => "gzip" ];
                          
                          @curl_setopt_array($ch, $options);
                          
                          //execute request
                          $r = curl_exec($ch);
                          var_dump($r);
                          curl_close($r);
                          
                          

                          In Developer Tools > Under Network: I don't see anything under the XHR tag but I do see a GET method under the All tab. Here's what the headers return:

                          Response headers (202 B)	
                          Connection	
                          close
                          Content-Type	
                          text/html; charset=UTF-8
                          Date	
                          Tue, 31 Jul 2018 21:43:07 GMT
                          Server	
                          Apache
                          Transfer-Encoding	
                          chunked
                          X-Powered-By	
                          PHP/5.6.23 ZendServer/8.5.5
                          Request headers (462 B)	
                          Accept	
                          text/html,application/xhtml+xm…plication/xml;q=0.9,*/*;q=0.8
                          Accept-Encoding	
                          gzip, deflate
                          Accept-Language	
                          en-US,en;q=0.5
                          Cache-Control	
                          max-age=0
                          Connection	
                          keep-alive
                          Cookie	
                          _ga=GA1.2.1222505240.153185123…ID=n8cr1upmf5arl790uh2j3uvl81
                          Host	
                          php.mywebdomain.com
                          Upgrade-Insecure-Requests	
                          1
                          User-Agent	
                          Mozilla/5.0 (Windows NT 6.1; W…) Gecko/20100101 Firefox/61.0
                          

                          First, I have set to POST but it always runs as GET and anytime I make any changes nothing works. Content Type is always text/html, Host is always my domain, etc..

                          However, if I run the HTML form using Ajax I get the following response on the JPG file I am uploading.

                          Access-Control-Allow-Origin	
                          *
                          Access-Control-Expose-Headers	
                          X-Total-Count
                          Connection	
                          keep-alive
                          Content-Encoding	
                          gzip
                          Content-Length	
                          381
                          Content-Type	
                          application/json
                          Date	
                          Tue, 31 Jul 2018 21:47:46 GMT
                          Vary	
                          Accept-Encoding
                          X-Vcap-Request-Id	
                          9a96e1d3-047a-442d-707b-e799e2783b7d
                          Request headers (473 B)	
                          Accept	
                          application/json
                          Accept-Encoding	
                          gzip, deflate
                          Accept-Language	
                          en-US,en;q=0.5
                          Connection	
                          keep-alive
                          Content-Length	
                          14919
                          Content-Type	
                          multipart/form-data; boundary=----------------8913314312416
                          Host	
                          api.labelary.com
                          Origin	
                          http://php.mydomain.com
                          Referer	
                          http://php.mydomain.com/INT/BAR_CODE/Zebra/img.php
                          User-Agent	
                          Mozilla/5.0 (Windows NT 6.1; W…) Gecko/20100101 Firefox/61.0
                          

                          I am not sure what I am doing wrong? All I can think of is the image is being passed from a form vs adding it w/o a HTML form when doing the cURL request.

                          jeepin81 All I can think of is the image is being passed from a form vs adding it w/o a HTML form when doing the cURL request.

                          cURL constructs multipart/form-data requests when POSTFIELDS is set to an array. The server isn't going to know what constructed the request.

                          You need to be looking at your requests, not just the responses. That will show any differences in what you're sending.

                          I had a look and tried:

                          $curl = curl_init();
                          curl_setopt_array($curl, [
                          	CURLOPT_URL => 'http://api.labelary.com/v1/graphics',
                          	CURLOPT_RETURNTRANSFER => true,
                          	CURLOPT_POSTFIELDS => ['file' => new cURLFile('c:\tmp\57633.png', 'image/png', '57633')],
                          	CURLOPT_ENCODING => 'deflate',
                          	CURLOPT_HTTPHEADER => [
                          		'Accept: application/json'
                          	],
                          	CURLINFO_HEADER_OUT => true // only so the request is saved for the info display later
                          ]);
                          
                          $response_body = curl_exec($curl);
                          $response_details = curl_getinfo($curl);
                          
                          var_export($response_details);
                          echo "\n\n\n";
                          echo $response_body;
                            24 days later
                            Write a Reply...