2017-01-19 6 views
0

Ich versuche, eine Datei zu Dropbox mit Indy 10 und XE8 hochzuladen. Während Dateiname wie 'file.txt' funktioniert es OK, aber mit 'файл.txt' oder so habe ich '????. Txt' auf DropBox. Ich las über Parameter mit utf-8, aber es ist nicht :-(mit Header arbeiten.Idhttp Indy Upload zu Dropbox mit utf-8 Dateiname

Wie kann ich eine Datei hochladen und utf-8 Dateinamen speichern?

procedure TSaveFilterForm.TestButtonClick(Sender: TObject); 
const 
    URL = 'https://content.dropboxapi.com/2/files/upload'; 
var 
    IdHTTP: TIdHTTP; 
    Source: TFileStream; 
    Res: String; 
begin       
    IdHTTP := TIdHTTP.Create(nil); 
    try 
    IdHTTP.HandleRedirects := True; 
    IdHTTP.IOHandler := TIdSSLIOHandlerSocketOpenSSL.Create(IdHTTP); 
    IdHTTP.Request.BasicAuthentication := False; 
    IdHTTP.Request.CustomHeaders.Values['Authorization'] := 'Bearer ' + AccessToken; 
    IdHTTP.Request.ContentType := 'application/octet-stream'; 
    Source := TFileStream.Create('c:\test.txt', fmOpenRead); 

    IdHTTP.Request.CustomHeaders.Values['Dropbox-API-Arg'] := 
     Format('{ "path": "%s", "mode": "overwrite"}', 
     ['/файл.txt']); // Dropbox => ????.txt 
    try 
     Res := IdHTTP.Post(URL, Source); 
    finally 
     Source.Free; 
    end; 
    finally 
    IdHTTP.Free; 
    end; 
end; 

Antwort

0

Für diese Anrufe mit Wenn Sie den Header "Dropbox-API-Arg" verwenden, müssen Sie ihn als "HTTP-Header-sicher" festlegen. Dies bedeutet, dass Sie den JSON-Stil "\ uXXXX" verwenden. Escape-Codes für das Zeichen 0x7F und alle Nicht-ASCII-Zeichen

Einige, aber nicht alle Sprachen/Bibliotheken tun das für Sie, zB für JavaScript, um dies selbst zu tun, könnten Sie etwas tun dies:

var charsToEncode = /[\u007f-\uffff]/g; 

function http_header_safe_json(v) { 
return JSON.stringify(v).replace(charsToEncode, 
function(c) { 
return '\\u' + ('000' + c.charCodeAt(0).toString(16)).slice(-4); 
} 
); 
} 

und dann so etwas wie:

'Dropbox-API-Arg': http_header_safe_json({ path: dropboxFilePath }) 

Es klingt wie Ihre Plattform nicht, dass für Sie tun, damit Sie diese in Ihrem Code implementieren möchten.

+0

[Delphi hat eine eigene JSON-Bibliothek] (http://docwiki.embarcadero.com/RADStudio/en/JSON). –

+0

@Greg danke. Ich habe eine solche Lösung für Delphi gefunden - http://drcooper.livejournal.com/4186.html. –

1

HTTP-Header dürfen keine Nicht-ASCII-Zeichen enthalten, nicht einmal UTF-8. Wenn Sie Nicht-ASCII-Zeichen in einem HTTP-Header senden müssen, müssen sie in einem ASCII-kompatiblen Format codiert sein.

In diesem Fall, da der Header in Frage JSON enthält, können Sie JSON eigene \uXXXX Syntax für die Codierung von Nicht-ASCII-Zeichen verwenden:

Jeder Codepunkt als Hexadezimalzahl dargestellt werden kann. Die Bedeutung einer solchen Zahl wird durch ISO/IEC 10646 bestimmt. Wenn der Codepunkt in der Basic Multilingual Plane liegt (U + 0000 bis U + FFFF), dann kann er als sechsstellige Folge dargestellt werden: ein umgekehrter Solidus, gefolgt von dem Kleinbuchstaben u, gefolgt von vier hexadezimalen Ziffern, die den Codepunkt codieren. Hexadezimale Ziffern können Ziffern (U + 0030 bis U + 0039) oder die hexadezimalen Buchstaben A bis F in Großbuchstaben (U + 0041 bis U + 0046) oder Kleinbuchstaben (U + 0061 bis U + 0066) sein. So kann beispielsweise eine Zeichenkette, die nur ein einzelnes umgekehrtes Soliduszeichen enthält, als "\u005C" dargestellt werden.

Zum Beispiel:

procedure TSaveFilterForm.TestButtonClick(Sender: TObject); 
const 
    URL = 'https://content.dropboxapi.com/2/files/upload'; 
var 
    IdHTTP: TIdHTTP; 
    Source: TFileStream; 
    Res: String; 
begin       
    IdHTTP := TIdHTTP.Create(nil); 
    try 
    IdHTTP.HandleRedirects := True; 
    IdHTTP.IOHandler := TIdSSLIOHandlerSocketOpenSSL.Create(IdHTTP); 
    IdHTTP.Request.BasicAuthentication := False; 
    IdHTTP.Request.CustomHeaders.Values['Authorization'] := 'Bearer ' + AccessToken; 
    IdHTTP.Request.ContentType := 'application/octet-stream'; 

    IdHTTP.Request.CustomHeaders.Values['Dropbox-API-Arg'] := Format(
     '{ "path": "%s", "mode": "overwrite"}', 
     ['/\u0444\u0430\u0439\u043B.txt'] 
    ); 

    Source := TFileStream.Create('c:\test.txt', fmOpenRead); 
    try 
     Res := IdHTTP.Post(URL, Source); 
     // alternatively, without using TFileStream manually: 
     // Res := IdHTTP.Post(URL, 'C:\test.txt'); 
    finally 
     Source.Free; 
    end; 
    finally 
    IdHTTP.Free; 
    end; 
end; 

Ich schlage vor, Sie eine JSON-Bibliothek verwenden, um den JSON Inhalt zu erstellen. Zum Beispiel können Sie Delphi eigene JSON framework in Delphi 2010 verwenden und später, zum Beispiel:

uses 
    ..., 
    // use DBXJSON in D2010-XE 
    // use Data.DBXJSON in XE2-XE5 
    // use System.JSON in XE6+ 
    ; 

procedure TSaveFilterForm.TestButtonClick(Sender: TObject); 
const 
    URL = 'https://content.dropboxapi.com/2/files/upload'; 
var 
    IdHTTP: TIdHTTP; 
    Json: TJSONObject; 
    Res: String; 
begin       
    IdHTTP := TIdHTTP.Create(nil); 
    try 
    IdHTTP.HandleRedirects := True; 
    IdHTTP.IOHandler := TIdSSLIOHandlerSocketOpenSSL.Create(IdHTTP); 
    IdHTTP.Request.BasicAuthentication := False; 
    IdHTTP.Request.CustomHeaders.Values['Authorization'] := 'Bearer ' + AccessToken; 
    IdHTTP.Request.ContentType := 'application/octet-stream'; 

    Json := TJSONObject.Create; 
    try 
     Json.AddPair('path', '/файл.txt'); 
     Json.AddPair('mode', 'overwrite'); 
     IdHTTP.Request.CustomHeaders.Values['Dropbox-API-Arg'] := Json.ToJSON; 
    finally 
     Json.Free; 
    end; 

    Res := IdHTTP.Post(URL, 'C:\test.txt'); 
    finally 
    IdHTTP.Free; 
    end; 
end; 

Es gibt viele 3rd-Party-JSON-Bibliotheken für Delphi, wenn Sie andere Delphi-Versionen unterstützen müssen.

+0

danke. Mit \ uXXXX funktioniert es gut. Ich habe TJSONObject nicht versucht, weil D2009 es nicht hat. –

+0

@OlegAdibekov gibt es viele JSON-Bibliotheken von Drittanbietern für Delphi, die 2009 unterstützen. –

+0

Ich benutze LkJSON, @RemyLebeau. Aber in diesem Fall wird es zu viel $ IFDEF sein. 1. DXE6 + + JSON; 2. D2010 + + DBXJSON; 3. D2009 (utf-8) + LkJSON; 4. Alt (Ansi) Delphi + LkJSON. Zu kompliziert. –