2017-01-19 9 views
0

Indy 10とXE8を使用してDropboxにファイルをアップロードしようとしています。 'file.txt'のようなファイル名は正常に動作しますが、 'файл.txt'などではDropBoxに '????? txt'があります。私は、UTF-8でのパラメータについて読み、それは:-(ヘッダでは動作しませんです。Idhttp IndyがUTF-8ファイル名を使用してDropboxにアップロード

どのように私は、ファイルをアップロードし、UTF-8のファイル名を保存することができますか?

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; 

答えて

0

をこれらの呼び出しのために"Dropbox-API-Arg"ヘッダーを使用する場合、 "HTTPヘッダーセーフ"にする必要があります。これはJSONスタイルの "\ uXXXX"を使用することを意味し、文字0x7Fとすべての非ASCII文字のエスケープコード

たとえば、JavaScriptの場合、あなた自身でこれを行うには、次のようなものがあります。この:

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); 
} 
); 
} 

、その後のようなもの:

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

プラットフォームがあなたのためにそれをしないようにあなたがあなたのコードでこれを実装したいと思うので、それは、聞こえます。

+0

[Delphiには独自のJSONライブラリがあります](http://docwiki.embarcadero.com/RADStudio/ja/JSON)。 –

+0

@Gregありがとうございます。私はデルファイのためのそのような解決策を見つけました - http://drcooper.livejournal.com/4186.html。ありがとう。 –

1

HTTPヘッダーには、UTF-8以外の非ASCII文字を使用することはできません。非ASCII文字をHTTPヘッダーで送信する必要がある場合は、ASCII互換の形式でエンコードする必要があります。この場合

、当該ヘッダはJSONが含まれているので、あなたは、非ASCII文字をエンコードするためJSON自身\uXXXX構文を使用することができます。

任意のコードポイントは16進数として表すことができます。そのような数の意味は、ISO/IEC 10646によって決定されます。コードポイントがBasic Multilingual Plane(U + 0000からU + FFFF)にある場合、コードポイントは6文字のシーケンスとして表されます:逆ソリッド、コードポイントをエンコードする4桁の16進数字のあとに小文字のuが続きます。 16進数字は、数字(U + 0030〜U + 0039)または16進文字A〜F(U + 0041〜U + 0046)または小文字(U + 0061〜U + 0066)のいずれかです。従って、例えば、単一の逆ソリッド文字のみを含む文字列は、「\u005C」と表現することができる。例えば

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; 

私はあなたがJSONコンテンツを作成するために、JSONライブラリを使用することをお勧め。たとえば、あなたは、Delphi 2010年にデルファイ独自のJSON frameworkを使用することができ、後で、例えば:あなたは、他のDelphiのバージョンをサポートする必要がある場合

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; 

サードパーティのJSONライブラリの多くは、デルファイのために利用可能があります。

+0

ありがとう。 \ uXXXXではうまく動作します。 D2009はそうではないので、私はTJSONObjectを試しませんでした。 –

+0

@OlegAdibekov 2009年をサポートするDelphiで利用できるサードパーティのJSONライブラリがたくさんあります。 –

+0

私はLkJSON、@ RemyLebeauを使用しています。しかし、この場合、$ IFDEFが多すぎます。 1. DXE6 + + JSON; D2010 + + DBXJSON; 2。 3. D2009(utf-8)+ LkJSON;古い(Ansi)Delphi + LkJSON。複雑すぎる。 –

関連する問題