- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我使用 Delphi XE2 构建了一个 DataSnap REST 服务器,并添加了一个通过 TStream 上传文件的服务器方法:
function TServerMethods.updateUploadFile(sFilename: string; UploadStream: TStream): string;
我希望能够从许多不同的客户端(Android、iOS 等)调用此方法,并且我一直在使用各种 REST 客户端(例如 Postman(Chrome 插件))测试该方法。但是到目前为止,我无法让它接受 HTTP POST 正文的内容。每当我发送 POST 命令时,我总是收到以下响应:
{"error":"Message content is not a valid JSON value."}
我尝试过使用各种不同的“内容类型”设置,但似乎没有任何效果。看起来 DataSnap 坚持要求内容是 JSON?我尝试将一些有效的 JSON 粘贴到内容区域中,但这也给出了相同的错误响应。
有人成功使用 TStream 作为 DataSnap 服务器方法的输入参数吗?我应该以另一种方式做吗?我多次使用TStream作为下载文件的输出参数,效果很好,这是我第一次尝试上传。
更新
我制作了一个快速的 Delphi DataSnap 客户端来测试 uploadFile 服务器方法,这一切都很好。然后,我使用 Fiddler 检查 Delphi 客户端用于发送内容正文中的 TStream 的 POST 命令,并注意到它是一个整数(字节)的 JSON 数组,例如[37,80,68,70,45,49,46,51,13,10]
。所以我可以看到我可以修改我的 Android/iOS 客户端以在 POST 之前将二进制数据转换为这种字节数组格式,但这是我可以不需要的开销。如果当 TStream 是返回参数时 DataSnap 流式传输原始二进制文件,为什么它不能流式传输原始二进制文件作为输入参数?
最佳答案
似乎在 POST 命令中将内容数据添加到请求正文时,DataSnap 服务器坚持认为该数据始终是 JSON。这就是为什么当使用 TStream 作为输入参数时,流数据会被 Delphi DataSnap 客户端转换为整数(字节)的 JSON 数组。这种格式的大小效率非常低,因为每个字节最多 3 位数字,再加上逗号,上传的数据大小可能会增长多达 4 倍。
因此,我所做的是将要上传的数据编码为 Base64。我的服务器方法现在如下所示:
function TServerMethods.updateUploadFile(sFilename: string; Base64Data: TJSONObject): string;
请注意,我将 Base64 字符串包装在 TJSONObject 中。这是因为,如果您只指定 String 类型,Delphi DataSnap 客户端将使用 GET 调用该方法,并尝试将整个 Base64 字符串放入 URL 路径中,从而导致“连接正常关闭”错误。使用 TJSONObject 会强制 DataSnap 使用 POST 并将数据放入内容正文中。传递的 JSON 对象是一对对象:
{"UploadedData":"JVBERi0xLjMNCiXi48B5SiWGTK3PaY.........."}
这样上传的数据量会小得多,传输速度也会更快。我仍然希望能够在内容正文中传输原始数据,但 DataSnap 不允许这样做。
关于delphi - 通过 TStream 将文件上传到 DataSnap REST 服务器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18110654/
我是一名优秀的程序员,十分优秀!