上传内容时,HTTP-Request中的内容类型值是什么?

时间:2013-02-19 16:33:57

标签: http http-upload

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

3 个答案:

答案 0 :(得分:22)

内容类型为per specification multipart/form-data

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

以下是使用1个普通字段和1个文件字段(使用<input name="textfield"><input type="file" name="filefield">时的HTML术语)的示例:

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

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

答案 1 :(得分:0)

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

答案 2 :(得分:0)

基于@BalusC的解决方案,我为WebClient类中的.NET构建提供了一些扩展方法,该方法不支持现成的分段上传。

用法

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

    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);

    }