【问题标题】:Whats Content-Type value within a HTTP-Request when uploading content?上传内容时 HTTP 请求中的 Content-Type 值是什么?
【发布时间】:2013-02-04 10:27:07
【问题描述】:

我需要从 http-trafic 中提取上传。怎么能这样?首先,请求方法将是 POST。其次,会有一个 Content-Type 头域。我不想提取公式数据,而是像邮件附件一样上传。

【问题讨论】:

  • 我注意到:Mime-Type 通常是multipart/form-data; 但我真的没有任何经验因此。我不明白为什么这个问题被否决了。

标签: http http-upload


【解决方案1】:

内容类型为per specificationmultipart/form-data

这是一种特殊的内容类型,可以在一个大请求中可视化为多个子请求。这些子请求中的每一个(一个表单数据元素)都有自己的一组标题。实际数据的内容类型在里面。

这是一个示例,它具有 1 个普通字段和 1 个文件字段(在 HTML 术语中,使用 <input name="textfield"><input type="file" name="filefield"> 时):

Content-Type: multipart/form-data;boundary=SOME_BOUNDARY

--SOME_BOUNDARY
content-disposition: form-data;name="textfield"
content-type: text/plain;charset=UTF-8

value of textfield here
--SOME_BOUNDARY
content-disposition: form-data;name="filefield";filename="some.ext"
content-type: application/octet-stream

binary file content here

--SOME_BOUNDARY--

至于解析和提取这些数据,几乎每种编程语言都为此提供了内置/第 3 方 API。由于您没有说明您使用的是哪一个,因此不可能给出有针对性的答案。例如,在 Java 的情况下,可以是第三方库 Apache Commons FileUpload,或者当您使用 Servlet 3.0 时,API 提供的 request.getPart() 方法。

【讨论】:

  • 我正在使用 c# 来实现这一点。我将信息存储在字节数组中。
【解决方案2】:

如果(我绝不是说这是正确的方法)您只想保存字节数组中的数据,您应该查看如何在以下位置读取 POST 正文: Reading POST body with bottle.py 读取数据然后创建一个新文件应该可以解决问题。

【讨论】:

    【解决方案3】:

    基于@BalusC 的解决方案,我为.NET 的内置WebClient 类做了一个小扩展方法,它不支持开箱即用的Multipart 上传。

    用法

    只需混合字符串值和文件(用#括起来)

        public void UploadMultipart()
        {
            var fileName = "/some/existing/file.ext";
            using (var client = new WebClient())
            {
                var values = new NameValueCollection();
                values.Add("id", Guid.NewGuid().ToString());
                values.Add("name", Path.GetFileNameWithoutExtension(fileName));
                values.Add("file", $"#{fileName}#");
    
                var result = client.UploadMultipart(address, method, values);
                var content = client.Encoding.GetString(result);
            }
        }
    

    扩展方法

        public static byte[] UploadMultipart(this WebClient client,
            string address, string method, NameValueCollection values)
        {
    
            string boundary = DateTime.Now.Ticks.ToString("x");
    
            client.Headers.Add("Content-Type", "multipart/form-data; boundary=" + boundary);
    
            var sb = new StringBuilder()
                .AppendLine();
    
            foreach (var key in values.AllKeys)
            {
                var contentDispositon = $"form-data;name=\"{key}\"";
                var contentType = $"text/plain;charset={client.Encoding.WebName}";
    
                var value = values[key];
    
                if (value.StartsWith("#") && value.EndsWith("#"))
                {
                    // if a value is enclosed in hashes we expect this to be a path to a file
                    // file=#/path/to/file.ext#
                    var fileName = value.Trim('#');
                    var file = File.ReadAllBytes(fileName);
                    value = client.Encoding.GetString(file);
    
                    contentType = "application/octet-stream";
                    contentDispositon = $"form-data;name=\"{key}\"filename=\"{Path.GetFileName(fileName)}\"";
                }
    
                sb.AppendLine($"--{boundary}")
                  .AppendLine($"Content-Disposition: {contentDispositon}")
                  .AppendLine($"Content-Type: {contentType}")
                  .AppendLine()
                  .AppendLine(value);
            }
    
            sb.AppendLine($"--{boundary}--");
    
            var data = client.Encoding.GetBytes(sb.ToString());
    
            return client.UploadData(address, method, data);
    
        }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-07-06
      • 1970-01-01
      • 2017-11-13
      • 2021-06-19
      • 1970-01-01
      • 2012-07-28
      相关资源
      最近更新 更多