当前位置: 首页 > 知识库问答 >
问题:

如何使用XMLHttpRequest和FormData对象在多部分/表单数据上设置自己的边界

终睿
2023-03-14

我一直在尝试找到一种方法,在使用FormData对象将文件附加到请求时,在XMLHttpRequest对象上设置我自己的边界。我看到过很多关于这个的帖子,每个人都说“不要设置边界,它会自动为您生成。”这不是我想要的。让我解释一下我需要什么,这样我就不会得到这种响应。

我有一个web服务endpoint,向其发送一个包含两个图像和一些json数据的多部分/表单数据请求。由于WCF无法通过多部分请求进行解析,因此我使用一些开源代码构建了自己的解析器。它的工作方式是,我定义了一个边界,用于分隔请求的每个部分,从那里一切都正常工作。因此,为了使我的解析类能够在输入流中找到任何内容,我必须能够将边界设置为服务器代码所期望的值。

我知道这是可以做到的,因为我已经用Fiddler做到了,而且一个同事可以在我们正在构建的应用程序中做到这一点,该应用程序调用了我的方法,但我正在尝试使用一个名为Postman的Chrome浏览器应用程序来实现它,该应用程序使用FormData对象发送多部分请求。除了请求生成自己的边界(通常类似于以下情况)之外,它还起作用:

----WebKitFormBoundaryQUWQnB6c7TzNzdcz

末尾的附加字符串是随机生成的,因此它永远不会相同,因此我无法使用此工具来测试我的endpoint,因为服务器无法知道要查找的边界。

我已经尝试使用我的边界设置内容类型标头,虽然请求显示要添加到请求的标头,但正文仍然使用随机边界。

所以问题是,我如何告诉FormData对象和/或XMLHttpRequest对象使用我的边界,而不是正在生成的随机边界?

我无法想象这是一件不寻常的事情,我的意思是到目前为止,我调用使用multipart/form-data的服务的所有经验都告诉我在api中设置边界的内容,并且没有人说“只是不要设置它,我们将使用生成的随机垃圾......”

同样作为视觉效果,这是我在标题中看到的:

Request Headers
POST /DHICachet.svc/json/DepositCheck HTTP/1.1
Host: dhiibews.securexfr.com
Connection: keep-alive
Content-Length: 514696
Origin: chrome-extension://fdmmgilgnpjigdojojpjoooidkmcomcm
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_6_8) AppleWebKit/537.11 (KHTML, like Gecko) Chrome/23.0.1271.64 Safari/537.11
Content-Type: multipart/form-data; boundary=myboundary
Cache-Control: no-cache
Accept: */*
Accept-Encoding: gzip,deflate,sdch
Accept-Language: en-US,en;q=0.8
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3
Cookie: ASP.NET_SessionId=zdepe2nhkz0vbhxiulzc2qq1

Request Payload
------WebKitFormBoundaryQUWQnB6c7TzNzdcz
Content-Disposition: form-data; name="item"; filename="Screen shot 2012-09-03 at 4.00.10 AM.png"
Content-Type: image/png


------WebKitFormBoundaryQUWQnB6c7TzNzdcz--

请注意,即使在请求标头中将“我的边界”设置为“我的边界”,主体也只会将在幕后生成的边界放入其中。还要注意的是,如果我不设置标题,它只会将其与随机边界放在一起。

共有3个答案

康照
2023-03-14

您可以将文件转换为二进制字符串,然后提交。代码是TypeScript,但JavaScript类似。

async uploadFile(myFile: File): Promise<boolean> {
        // Get the binary string from the file in order to send the file with `multipart/form-data`
        const contentPromise = new Promise<string>((resolve) => {
            const reader = new FileReader()
            reader.onload = async function (evt) {
                const pdfContent: string = evt?.target?.result as string
                resolve(pdfContent)
            }

            reader.readAsBinaryString(myFile)
        })
        const binaryContent = await contentPromise

        // Send the request
        const path = `api/update-file`
        const content = `--WebAppBoundary
Content-Disposition: form-data; name="myFile"; filename="${myFile.name}"
Content-Type: application/pdf

${binaryContent}
--WebAppBoundary--`

        const requestOptions = {
            method: 'POST',
            headers: {
                'Content-Type': 'multipart/form-data; boundary=WebAppBoundary'
            },
            body: content
        }

        const response: { code: number; message: string } = await (await fetch(path, requestOptions)).json()

        // Return the response
        return response.code === 200
    }
越嘉茂
2023-03-14

我有一个类似的问题,对我来说,在发布帖子时将内容类型标头设置为未定义的修复了这个问题...'Content-Type':未定义的

我相信浏览器会自动正确处理表单数据的发布,并为您设置所需的内容类型标题,如果未设置,则包括边界。所以,这意味着服务器上不需要请求头的特殊解析逻辑。

麹正业
2023-03-14

这并不能真正回答我的问题,但我确实找到了解决办法。我突然意识到,通过对内容类型标题进行字符串运算,我实际上可以检测到正在通过的边界。我刚刚在代码中添加了以下内容:

string contenttype = _ctx.IncomingRequest.Headers["Content-Type"].ToString();
string boundary = contenttype.Substring(contenttype.IndexOf('=') + 1);

这允许我接受任何调试边界。然而,我仍然需要我们的具体生产边界。

 类似资料:
  • 我正在使用本指南向使用JMeter:https://www.blazemeter.com/blog/testing-advanced-rest-api-file-uploads-jmeter的服务器发送多部分POST请求 在这个请求中有几个部分,如文件、一些字符串和JSON。 问题是,尽管我在“Content type”字段中指定了边界,但JMeter设置了它想要的任何内容,结果是服务器(Wild

  • 没有边界的多部分/表单数据请求是否有效?根据规范,当有超过1个部分时,使用边界将它们分开(并且该边界不应该是身体的一部分)。我有一个请求,其中有一个单一的主体作为原始内容或文件,在内容类型中,我们传递“多部分/表单数据”。这种要求实际上有效吗?

  • 表单概述 表单(<form>)用来收集用户提交的数据,发送到服务器。比如,用户提交用户名和密码,让服务器验证,就要通过表单。表单提供多种控件,让开发者使用,具体的控件种类和用法请参考 HTML 语言的教程。本章主要介绍 JavaScript 与表单的交互。 <form action="/handling-page" method="post"> <div> <label for="na

  • 问题内容: 我是angular.js的初学者,但是对基础知识有很好的了解。 我要做的是上传文件和一些表单数据作为多部分表单数据。我读到这不是angular的功能,但是3rd party库可以做到这一点。我已经通过git克隆了angular-file-upload,但是仍然无法发布简单的表单和文件。 有人可以提供如何执行此操作的示例,html和js吗? 问题答案: 首先 您无需对结构进行任何特殊更改

  • 当我点击这个api时,我得到错误“415:Unsupported Media type”,这意味着不受支持的头。我想将文件从ARC加载到控制器。 我在pom.xml文件中添加了一些maven依赖项。 我的pom文件:

  • 我正试图弄明白这一点。我的代码没有收到任何有用的错误消息,所以我使用了其他东西来生成一些东西。我在错误信息后附加了该代码。我已经找到了一个关于它的教程,但我不知道如何用我所拥有的实现它。这就是我目前拥有的: 错误: 对象{消息:“此资源不支持请求实体的媒体类型‘multipart/form data’。”,例外消息:“没有MediaTypeFormatter可用于读取媒体类型为“multipart