【问题标题】:POST binary data from browser to JFrog / Artifactory server without using form-dataPOST 二进制数据从浏览器到 JFrog / Artifactory 服务器而不使用表单数据
【发布时间】:2017-07-19 00:19:16
【问题描述】:

所以我们在前端得到一个文件(图像文件),如下所示:

//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
   };

我想知道的是 - 有没有办法将此文件发布到服务器,而不将文件包含为表单数据?问题是我发送 HTTP POST 请求的服务器在收到请求时并不真正知道如何存储表单数据。

我相信这是正确的做法,但我不确定。

  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
  )

【问题讨论】:

  • 为什么你不确定你的方法是否是“正确的方法”?是的,您应该可以将 POST BlobFile 实例发送到服务器
  • @AlexanderMills:但是你的服务器必须知道在接收到 image/jpeg 类型的 POST 请求时要做什么。你用的是什么服务器?
  • 我们需要 HTTP POST/PUT 到 JFrog Artifactory 服务器 - 我最终使用我们的服务器作为 Artifactory 服务器的代理。我将添加一个答案,说明我们是如何做到的。也许有人可以看看我的答案并展示如何避免代理。

标签: ajax image http fetch-api


【解决方案1】:

您可以直接将文件附加到请求正文。 Artifactory 不支持表单上传(和it doesn't look like they plan to

您仍然需要以某种方式代理请求以避免 CORS 问题,如果您使用的是用户凭据,则应谨慎对待它们。此外,您可以使用 http-proxy-middleware 之类的库来避免编写/测试/维护代理逻辑。

<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】:

    我们的前端无法将 HTTP POST 直接发送到 JFrog/Artifactory 服务器。所以我们最终使用了 Node.js 服务器作为代理,这不是很理想。

    前端:

    // 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'
              }
            })
          },
    

    后端:

    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;
    

    并不是说我们必须使用 PUT 请求将图像发送到 Artifactory,而不是 POST,这与 Artifactory 相关(engci-maven.nabisco.com 服务器是 Artifactory 服务器)。我记得,当我尝试直接从我们的前端发布到另一台服务器时遇到了 CORS 问题,所以我们不得不使用我们的服务器作为代理,这是我宁愿避免的事情,但现在还好。

    【讨论】:

      猜你喜欢
      • 2017-12-24
      • 2011-12-04
      • 1970-01-01
      • 1970-01-01
      • 2014-07-27
      • 2015-09-15
      • 1970-01-01
      • 1970-01-01
      • 2013-03-13
      相关资源
      最近更新 更多