expertenaustausch > comp.lang.* > comp.lang.delphi.misc

Christian Schmitt (25.03.2020, 10:06)
Hallo Leute,

ich weiß nicht ob ihr mir helfen könnt aber ich probiere es mal: Ich habe ein Mediawiki zu Hause und da ich hier sehr oft Dateien hochladen muß, habe ich mir einen Uploadhelper in Delphi geschrieben. Dieser nutzt die Komponente TWebbrowser.

Dabei wird einfach ein POST wie folgt gesendet (Code, siehe unten). Seit Mediawiki 1.27 jedoch funktioniert dies nicht mehr. Wenn ich manuell in der TWebbrowser-Komponente eine Datei hochlade, dann gehts. Nutze ich meine Funktion, dann erhalte ich im Wiki die Meldung, dass meine Sitzungsdaten ausgelaufen wären. Muß ich hier irgend welche Sitzungsdaten mitsenden oder soetwas? Ich habe von Web, Cookies & Co leider keine Ahnung :-)

Vielleicht weiß ja jemand etwas und kann mir helfen.

Gruß

Mein Code:

type
aos=array of ansistring;

function TForm2.FileUpload(const pDisp: IDispatch;Filename:string):string;
var
CurrentBrowser: IWebBrowser2;
Doc3 : IHTMLDocument3;
a,b,c,d:aos;
begin
CurrentBrowser := pDisp as IWebBrowser2;
Doc3 := currentBrowser.Document as IHTMLDocument3;
Result:=ExtractFileName(Filename);
RemoveIllegalChars(Result);
SetLength(a,7);
SetLength(b,7);
SetLength(c,1);
SetLength(d,1);
a[0]:='wpSourceType';
a[1]:='wpDestFile';
a[2]:='wpUploadDescription';
a[3]:='wpUpload';
a[4]:='wpDestFileWarnigAck';
a[5]:='wpForReUpload';
b[0]:='file';
b[1]:=Result;
b[2]:='';
b[3]:='Datei hochladen';
b[4]:='';
b[5]:='';
b[6]:='';
c[0]:='wpUploadFile';
d[0]:=Filename;
UploadFilesHttpPost(wb1,edtUploadURL.Text,a,b,c,d) ;
end;

procedure UploadFilesHttpPost(const wb:TWebBrowser; const URLstring: string; names, values, nFiles, vFiles: aos) ;
var
strData, n, v, boundary: AnsiString;
URL: OleVariant;
Flags: OleVariant;
PostData: OleVariant;
Headers: OleVariant;
idx: Integer;

ms: TMemoryStream;
ss: TStringStream;
begin
if Length(names) <> Length(values) then
raise Exception.Create('UploadFilesHttpPost: Names and Values must have the same length.') ;
if Length(nFiles) <> Length(vFiles) then
raise Exception.Create('UploadFilesHttpPost: FileNames and FileValues must have the same length.') ;

URL := 'about:blank';
Flags := NavNoHistory or NavNoReadFromCache or NavNoWriteToCache or NavAllowAutosearch;
wb.Navigate2(URL, Flags) ;
while wb.ReadyState<>1
do Application.ProcessMessages;

// anything random that WILL NOT occur in the data.
boundary := '---------------------------123456789';

strData := '';

for idx := Low(nFiles) to High(nFiles) do
begin
n := nFiles[idx];
v := vFiles[idx];

strData := strData + '--' + boundary + #13#10 + 'Content-Disposition: form-data; name="' + n + '"; filename="' + ExtractFileName(v) + '"' +#13#10;

if v = '' then
begin
strData := strData + 'Content-Transfer-Encoding: binary'+#13#10#13#10;
end
else
begin
if (CompareText(Uppercase(ExtractFileExt(v)), '.JPG') = 0) or (CompareText(Uppercase(ExtractFileExt(v)), '.JPEG') = 0) then
begin
strData := strData + 'Content-Type: image/pjpeg'#13#10#13#10;
end
else if (CompareText(Uppercase(ExtractFileExt(v)), '.PNG') = 0) then
begin
strData := strData + 'Content-Type: image/x-png'#13#10#13#10;
end
else if (CompareText(Uppercase(ExtractFileExt(v)), '.PDF') = 0) then
begin
strData := strData + 'Content-Type: application/pdf'#13#10#13#10;
end
else if (CompareText(Uppercase(ExtractFileExt(v)), '.HTML') = 0) then
begin
end;

//strData := strData + 'Content-Type: text/html'#13#10#13#10;

ms := TMemoryStream.Create;
try
ms.LoadFromFile(v) ;
ss := TStringStream.Create('') ;
try
ss.CopyFrom(ms, ms.Size) ;

strData := strData + AnsiString(ss.DataString) + #13#10;
finally
ss.Free;
end;
finally
ms.Free;
end;
end;

end;

for idx := Low(names) to High(names) do
begin
n := names[idx];
v := values[idx];

strData := strData + '--' + boundary + #13#10 + 'Content-Disposition: form-data; name="' + n + '"' + #13#10#13#10 + v + #13#10;
end;
strData := strData + '--' + boundary + '--'#13#10; // FOOTER
strData := strData + #0;

{2. you must convert a string into variant array of bytes and every character from string is a value in array}
PostData := VarArrayCreate([0, Length(strData) - 1], varByte) ;

{ copy the ordinal value of the character into the PostData array}
for idx := 1 to Length(strData) do PostData[idx-1] := Ord(strData[idx]) ;

{3. prepare headers which will be sent to remote web-server}
Headers := 'Referer:
Headers := Headers + 'Content-Type: multipart/form-data; boundary=' + boundary + #13#10;

{4. you must navigate to the URL with your script and send as parametersyour array with POST-data and headers}
URL := URLstring;
wb.Navigate2(URL, Flags, EmptyParam, PostData, Headers) ;
while wb.ReadyState<>1
do Application.ProcessMessages;
end;
Christian Schmitt (26.03.2020, 12:14)
Ich habe schon mal soweit was herausgefunden: Es liegt wohl an einem "wpEditToken", der als Parameter des POST befehls mitgesendet werden muß. Der ist wohl seitenspeziefisch. Beim Aufruf der Uploadseite wird er vom Mediawiki wohl generiert und dem Browser übergeben, beim POST schickt der Browser ihn wieder mit. Nur wie komme ich an diesen Token dran. Hat jemand eine Idee?
Ähnliche Themen