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...