支持的组件
当 HTTP 客户端发送 multipart/form-data 数据流时,服务器默认将其保存在内存中。当文件较大时,服务器可能会抛出内存不足异常。为避免此类异常,服务器提供了 HTTPUploadFiles 属性,允许您配置 POST 数据流的处理方式:内存流或文件流。若选择文件流方式,接收到的数据流将直接存储到硬盘,从而避免内存问题。
要将服务器配置为以文件流方式保存 multipart/form-data 数据流,请按照以下步骤操作:
1. 将属性 HTTPUploadFiles.StreamType = pstFileStream 设置好。使用此配置后,服务器将把这些数据流存储到硬盘。
2. 您可以配置将文件存储为文件流的最小字节数。默认值为零,即所有数据流均以文件流方式存储。
3. 通过 SaveDirectory 属性指定数据流的存储文件夹;若未设置,则存储在应用程序所在的目录。
4. 当客户端发送 multipart/form-data 时,内容以边界(boundary)编码。若启用了 RemoveBoundaries 属性,则在完整数据流接收完毕后,将自动提取边界中的内容。
示例代码
首先创建一个新的服务器实例,并将数据流设置为以文件流方式保存。
oServer := TsgcWebSocketHTTPServer.Create(nil);
oServer.Port := 5555;
oServer.HTTPUploadFiles.StreamType := pstFileStream;
oServer.Active := True;
然后创建一个包含以下配置的 HTML 文件。
<html>
<head><title>sgcWebSockets - Upload Big File</title></head>
<body>
<form action="http://127.0.0.1:5555/file" method="post" enctype="multipart/form-data" accept-charset="UTF-8">
<input type="file" name="file_1" />
<input type="submit" />
</form>
</body>
</html>
最后,用浏览器打开该 HTML 文件并向服务器发送一个文件。服务器将创建一个扩展名为 ".sgc_ps" 的新文件流,并在数据流完整接收后自动从边界中提取文件。
以下 2 个事件可用于自定义文件上传流程(需启用 HTTPUploadFiles.RemoveBoundaries 属性)。
OnHTTPUploadBeforeSaveFile
该事件在文件保存之前触发,允许您自定义所接收文件的名称。
procedure OnHTTPUploadBeforeSaveFileEvent(Sender: TObject; var aFileName: string; var aFilePath: string);
begin
if aFileName = "test.jpg" then
aFileName := "custom_test.jpg";
end;
OnHTTPUploadAfterSaveFile
该事件在文件保存之后触发,允许您获知已保存文件的名称。
procedure OnHTTPUploadBeforeSaveFileEvent(Sender: TObject; const aFileName: string; const aFilePath: string); begin DoLog("File Received: " + aFileName);end;
OnHTTPUploadReadInput
该事件在解码器读取到非文件类型的输入值时触发(例如:表单中包含 name、date 等字段变量时)。
procedure OnHTTPUploadReadInputEvent(Sender: TObject; const aName: string; const aValue: string); begin DoLog("Input value received: " + aName + ":" + aValue);end;