mormot multipart上传文件
首先修改mormot的MultiPartFormDataEncode()
function MultiPartFormDataEncode(const MultiPart: TMultiPartDynArray; var MultiPartContentType, MultiPartContent: RawUTF8): boolean; var len, boundcount, filescount, i: integer; boundaries: array of RawUTF8; bound: RawUTF8; W: TTextWriter; temp: TTextWriterStackBuffer; procedure NewBound; var random: array[1..3] of cardinal; begin FillRandom(@random,3); bound := BinToBase64(@random,SizeOf(Random)); SetLength(boundaries,boundcount+1); boundaries[boundcount] := bound; inc(boundcount); end; begin result := false; len := length(MultiPart); if len=0 then exit; boundcount := 0; filescount := 0; W := TTextWriter.CreateOwnedStream(temp); try // header - see https://www.w3.org/Protocols/rfc1341/7_2_Multipart.html NewBound; //MultiPartContentType := 'Content-Type: multipart/form-data; boundary='+bound; MultiPartContentType := 'multipart/form-data; boundary='+bound; for i := 0 to len-1 do with MultiPart[i] do begin if FileName='' then W.Add('--%'#13#10'Content-Disposition: form-data; name="%"'#13#10+ 'Content-Type: %'#13#10#13#10'%'#10'--%'#13#10, [bound,Name,ContentType,Content,bound]) else begin // if this is the first file, create the header for files if filescount=0 then begin if i>0 then NewBound; W.Add('Content-Disposition: form-data; name="files"'#13#10+ 'Content-Type: multipart/mixed; boundary=%'#13#10#13#10,[bound]); end; inc(filescount); W.Add('--%'#13#10'Content-Disposition: form-data; name="%" filename="%"'#13#10+ 'Content-Type: %'#13#10,[bound, Name, FileName,MultiPartContentType]); // W.Add('--%'#13#10'Content-Disposition: file; filename="%"'#13#10+ // 'Content-Type: %'#13#10,[bound,FileName,ContentType]); if Encoding<>'' then W.Add('Content-Transfer-Encoding: %'#13#10,[Encoding]); W.AddCR; W.AddString(MultiPart[i].Content); W.Add(#13#10'--%'#13#10,[bound]); end; end; // footer multipart for i := boundcount-1 downto 0 do W.Add('--%--'#13#10, [boundaries[i]]); W.SetText(MultiPartContent); result := True; finally W.Free; end; end;
var part: SynCommons.TMultiPart; parts: SynCommons.TMultiPartDynArray; sFile, fileName : string; fs: Tfilestream; rs: TRawByteStringStream; data, ContentType : RawUTF8; begin //打开文件 if not OpenDialog1.Execute then Exit; sFile := OpenDialog1.FileName; fileName := AnsiToUtf8(ExtractFileName(sFile)); try fs := Tfilestream.Create(sFile, fmOpenRead); rs := TRawByteStringStream.Create; rs.CopyFrom(fs, fs.Size); SetLength(parts, 1); part.ContentType := 'multipart/form-data;boundary='; part.Name := 'xssjdb'; part.FileName := fileName;//文件名,上传至服务端的文件名,一般是原文件名,可以是别名 part.Content := rs.DataString; //文件内容 parts[0] := part; //添加参数, 服务端以request的query参数接收。与普通参数一样 syncommons.MultiPartFormDataAddField('filename', fileName, parts); SynCommons.MultiPartFormDataEncode(parts, ContentType, data); finally rs.Free; fs.Free; end; if http.Post('访问的地址url', data, ContentType) = 200 then begin //Memo1.Lines.Add(Utf8ToAnsi(http.Content)); end; end;