POST binary data from browser to JFrog / Artifactory server without using form-data

ぐ巨炮叔叔 提交于 2019-12-08 07:52:22

问题


So we get a file (an image file) in the front-end like so:

//html

  <input type="file" ng-change="onFileChange">

//javascript

  $scope.onFileChange = function (e) {
      e.preventDefault();
      let file = e.target.files[0];
      // I presume this is just a binary file
      // I want to HTTP Post this file to a server
      // without using form-data
   };

What I want to know is - is there a way to POST this file to a server, without including the file as form-data? The problem is that the server I am send a HTTP POST request to, doesn't really know how to store form-data when it receives a request.

I believe this is the right way to do it, but I am not sure.

  fetch('www.example.net', { // Your POST endpoint
    method: 'POST',
    headers: {
      "Content-Type": "image/jpeg"
    },
    body: e.target.files[0] // the file
  })
   .then(
    response => response.json() // if the response is a JSON object
  )

回答1:


You can directly attach the file to the request body. Artifactory doesn't support form uploads (and it doesn't look like they plan to)

You'll still need to proxy the request somehow to avoid CORS issues, and if you're using user credentials, you should be cautious in how you treat them. Also, you could use a library like http-proxy-middleware to avoid having to write/test/maintain the proxy logic.

<input id="file-upload" type="file" />

<script>
function upload(data) {
  var file = document.getElementById('file-upload').files[0];
  var xhr = new XMLHttpRequest();
  xhr.open('PUT', 'https://example.com/artifactory-proxy-avoiding-cors');
  xhr.send(file);
}
</script>



回答2:


Our front-end could not HTTP POST directly to the JFrog/Artifactory server. So we ended up using a Node.js server as a proxy, which is not very ideal.

Front-end:

// in an AngularJS controller:

     $scope.onAcqImageFileChange = function (e) {

          e.preventDefault();
          let file = e.target.files[0];
          $scope.acqImageFile = file;
      };

// in an AngularJS service

     createNewAcqImage: function(options) {

        let file = options.file;

        return $http({
          method: 'POST',
          url: '/proxy/image',
          data: file,
          headers: {
            'Content-Type': 'image/jpeg'
          }
        })
      },

Back-end:

const express = require('express');
const router = express.Router();

router.post('/image', function (req, res, next) {

  const filename = uuid.v4();

  const proxy = http.request({
    method: 'PUT',
    hostname: 'engci-maven.nabisco.com',
    path: `/artifactory/cdt-repo/folder/${filename}`,
    headers: {
      'Authorization': 'Basic ' + Buffer.from('cdt-deployer:foobar').toString('base64'),
    }
  }, function(resp){
    resp.pipe(res).once('error', next);
  });

  req.pipe(proxy).once('error', next);
});

module.exports = router;

not that we had to use a PUT request to send an image to Artifactory, not POST, something to do with Artifactory (the engci-maven.nabisco.com server is an Artifactory server). As I recall, I got CORS issues when trying to post directly from our front-end to the other server, so we had to use our server as a proxy, which is something I'd rather avoid, but oh well for now.



来源:https://stackoverflow.com/questions/45179058/post-binary-data-from-browser-to-jfrog-artifactory-server-without-using-form-d

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!