2016-11-19 35 views
-1

TIdHTTPとTIdMultipartFormDataStreamの状況があります。idHTTPの文字エンコーディングエラー

私のコードは次のとおりです。

FormPHP := TIdMultiPartFormDataStream.Create; 
    FormPHP.AddFile('imagem',AImagem,'image/jpeg'); 
    FormPHP.AddFormField('iduser',AIDUser,'text/plain'); 
    FormPHP.AddFormField('nome',ANome,'text/plain'); 
    FormPHP.AddFormField('data',AData,'text/plain'); 
    FormPHP.AddFormField('hora',AHora,'text/plain'); 
    FormPHP.AddFormField('mensagem',AMensagem,'text/plain'); 
    FormPHP.AddFormField('latitude','1','text/plain'); 
    FormPHP.AddFormField('longitude','1','text/plain'); 

    Response := TStringStream.Create('', TEncoding.ANSI); 

    HTTP:= TIdHTTP.Create(self); 
    HTTP.Request.CustomHeaders.Clear; 
    HTTP.Request.Clear; 
    HTTP.Request.ContentType:= 'multipart/form-data'; //application/x-www-form-urlencoded 
    HTTP.Request.ContentEncoding:= 'MeMIME'; 
    HTTP.Request.CharSet:= 'utf-8'; 
    HTTP.Request.Referer:= 'http://observadordecascavel.blog.br/cadastro.php'; 
    HTTP.Post('http://observadordecascavel.blog.br/cadastro.php',FormPHP,Response); 

これはPHPスクリプトです:説明する

<?php 
    #cadastro.php - Cadastra os dados enviados na tabela online. 
    $mysqli = new mysqli("mysqlhost","username","password","dbname"); 

    $iduser   = $_POST['iduser']; 
    $nome   = $_POST['nome']; 
    $data   = $_POST['data']; 
    $hora   = $_POST['hora']; 
    $mensagem  = $_POST['mensagem']; 
    $latitude  = $_POST['latitude']; 
    $longitude  = $_POST['longitude']; 
    $imagem   = $_FILES["imagem"]['tmp_name']; 
    $tamanho  = $_FILES['imagem']['size']; 

    if ($imagem != "none") 
    { 
     $fp = fopen($imagem, "rb"); 
     $conteudo = fread($fp, $tamanho); 
     $conteudo = addslashes($conteudo); 
     fclose($fp); 

     $queryInsercao = "INSERT INTO tabpainel (iduser, nome, data, hora, mensagem, latitude, longitude, imagem) VALUES ('$iduser', '$nome', '$data','$hora','$mensagem', '$latitude', '$longitude', '$conteudo')"; 

     mysqli_query($mysqli,$queryInsercao) or die("Algo deu errado ao inserir o registro. Tente novamente."); 

     if(mysqli_affected_rows($mysqli) > 0) 
      print "Sucesso!"; 
     else 
      print "Não foi possível inserir o registro"; 
    } 
    else 
     print "Não á foi possível carregar a imagem."; 
    ?> 

:私のアプリケーションは、このPHPスクリプトとPHPにこれらのフィールドを投稿するには、MySQLデータベースにデータを保存し、 "Sucesso!"の応答を返します。データが保存されたことをユーザーに知らせるためにアプリケーションに送信します。このテキスト応答はANSIでエンコードされています。 TStringStreamのエンコードをTEncoding.ANSIに変更する必要があるときに、何か問題が発生したときに「ナオ」という単語を認識できるようになったことがわかりました。

投稿まで、変数AMensagemはOKですが、PHPがテキストを受け取ったときは正しくありません。このようなテキスト:「áÁéÉ」は、「= E1 = C1 = E9 = C9」のように見えます。これはmysqlデータベースに保存されます。

問題がidHTTPかTIdMultipartFormDataStreamであるのか、PHPコードであってもわかりません。すべてうまく動作します、それは私がそれがうまくいかない理由の手がかりがないエンコーディングです。

答えて

1

サーバーに送信されるテキストがUTF-8でエンコードされていません。

AddFormField()のすべてのコールで、AContentTypeパラメータの代わりにACharsetパラメータにtext/plainメディアタイプが指定されています。 AddFile()とは異なり、3番目のパラメータAddFormField()は文字セットであり、4番目のパラメータはメディアタイプです。無効な文字セット、TIdMultipartFormDataStreamバイト$3F'?')のようインディの組み込み生8ビット符号化の代わりに、それぞれ、Unicode文字をバイト$00 - $FFとしてU+0000 - U+00FFをコードする、他のすべての文字を使用して終わるを通過させることによって

function AddFormField(const AFieldName, AFieldValue: string; const ACharset: string = ''; const AContentType: string = ''; const AFileName: string = ''): TIdFormDataField; overload; 

を送信するテキストは、最初の範囲に入るようにになります。

TIdFormDataField現在、文字セットはTIdMultipartFormDataStreamまたはTIdHTTP(現在進行中です)から継承されていないため、フィールド単位で指定する必要があります。

MeMIMEは有効なContentEncoding値ではありません。とにかくmultipart/form-dataの投稿にはContentEncodingの値を設定しないでください。また

FormPHP := TIdMultiPartFormDataStream.Create; 

FormPHP.AddFile('imagem', AImagem, 'image/jpeg'); 
FormPHP.AddFormField('iduser', AIDUser, 'utf-8'); 
FormPHP.AddFormField('nome', ANome, 'utf-8'); 
FormPHP.AddFormField('data', AData, 'utf-8'); 
FormPHP.AddFormField('hora', AHora, 'utf-8'); 
FormPHP.AddFormField('mensagem', AMensagem, 'utf-8'); 
FormPHP.AddFormField('latitude', '1'); 
FormPHP.AddFormField('longitude', '1'); 

Response := TStringStream.Create(''); 

HTTP := TIdHTTP.Create(Self); 
HTTP.Request.Referer := 'http://observadordecascavel.blog.br/cadastro.php'; 
HTTP.Post('http://observadordecascavel.blog.br/cadastro.php', FormPHP, Response); 

がより代わりにこのような何か試してみてください

FormPHP := TIdMultiPartFormDataStream.Create; 

FormPHP.AddFile('imagem', AImagem, 'image/jpeg'); 
FormPHP.AddFormField('iduser', AIDUser).Charset := 'utf-8'; 
FormPHP.AddFormField('nome', ANome).Charset := 'utf-8'; 
FormPHP.AddFormField('data', AData).Charset := 'utf-8'; 
FormPHP.AddFormField('hora', AHora).Charset := 'utf-8'; 
FormPHP.AddFormField('mensagem', AMensagem).Charset := 'utf-8'; 
FormPHP.AddFormField('latitude', '1'); 
FormPHP.AddFormField('longitude', '1'); 

Response := TStringStream.Create(''); 

HTTP := TIdHTTP.Create(Self); 
HTTP.Request.Referer := 'http://observadordecascavel.blog.br/cadastro.php'; 
HTTP.Post('http://observadordecascavel.blog.br/cadastro.php', FormPHP, Response); 

いずれかの方法を、フィールドのテキストが代わりにはAnsiのUTF-8を使用してエンコードされます。


更新:今、それをデフォルトでquoted-printableTIdFormDataField.ContentTransferプロパティを設定しAddFormField()、と述べました。しかし、PHPの$_POSTはデフォルトでquoted-printableをデコードしない、手動でquoted_printable_decode()を呼び出す必要があります:

$iduser   = quoted_printable_decode($_POST['iduser']); 
$nome   = quoted_printable_decode($_POST['nome']); 
$data   = quoted_printable_decode($_POST['data']); 
$hora   = quoted_printable_decode($_POST['hora']); 
$mensagem  = quoted_printable_decode($_POST['mensagem']); 
$latitude  = quoted_printable_decode($_POST['latitude']); 
$longitude  = quoted_printable_decode($_POST['longitude']); 

あなたがquoted-printableを使用してUTF-8テキストをエンコードするTIdFormDataFieldしたくない場合は、あなたがContentTransferプロパティを設定することができます代わり8bit:あるいは

FormPHP.AddFormField('iduser', AIDUser, 'utf-8').ContentTransfer := '8bit'; 
FormPHP.AddFormField('nome', ANome, 'utf-8').ContentTransfer := '8bit'; 
FormPHP.AddFormField('data', AData, 'utf-8').ContentTransfer := '8bit'; 
FormPHP.AddFormField('hora', AHora, 'utf-8').ContentTransfer := '8bit'; 
FormPHP.AddFormField('mensagem', AMensagem, 'utf-8').ContentTransfer := '8bit'; 
FormPHP.AddFormField('latitude', '1'); 
FormPHP.AddFormField('longitude', '1'); 

with FormPHP.AddFormField('iduser', AIDUser) do begin 
    Charset := 'utf-8'; 
    ContentTransfer := '8bit'; 
end; 
with FormPHP.AddFormField('nome', ANome) do begin 
    Charset := 'utf-8'; 
    ContentTransfer := '8bit'; 
end; 
with FormPHP.AddFormField('data', AData) do begin 
    Charset := 'utf-8'; 
    ContentTransfer := '8bit'; 
end; 
with FormPHP.AddFormField('hora', AHora) do begin 
    Charset := 'utf-8'; 
    ContentTransfer := '8bit'; 
end; 
with FormPHP.AddFormField('mensagem', AMensagem) do begin 
    Charset := 'utf-8'; 
    ContentTransfer := '8bit'; 
end; 
FormPHP.AddFormField('latitude', '1'); 
FormPHP.AddFormField('longitude', '1'); 

いずれかの方法は、あなたが再び元のPHPコードを使用することができます。

$iduser   = $_POST['iduser']; 
$nome   = $_POST['nome']; 
$data   = $_POST['data']; 
$hora   = $_POST['hora']; 
$mensagem  = $_POST['mensagem']; 
$latitude  = $_POST['latitude']; 
$longitude  = $_POST['longitude']; 

あなたがquoted-printableを使用するかどうかは、PHPの変数はUTF-8でエンコードされたテキストを保持することになります。

(ISO-8859-1にデコード)
  1. utf8_decode()を::

    $iduser   = utf8_decode($iduser); 
    $nome   = utf8_decode($nome); 
    $data   = utf8_decode($data); 
    $hora   = utf8_decode($hora); 
    $mensagem  = utf8_decode($mensagem); 
    $latitude  = utf8_decode($latitude); 
    $longitude  = utf8_decode($longitude); 
    
  2. あなたは変数が別のエンコーディングにする必要がある場合は、必要に応じていずれかを使用することによって、それらを変換する必要があります

    mb_convert_encoding()

    $iduser   = mb_convert_encoding($iduser, 'desired charset', 'utf-8'); 
    $nome   = mb_convert_encoding($nome), 'desired charset', 'utf-8'); 
    $data   = mb_convert_encoding($data, 'desired charset', 'utf-8'); 
    $hora   = mb_convert_encoding($hora, 'desired charset', 'utf-8'); 
    $mensagem  = mb_convert_encoding($mensagem, 'desired charset', 'utf-8'); 
    $latitude  = mb_convert_encoding($latitude, 'desired charset', 'utf-8'); 
    $longitude  = mb_convert_encoding($longitude, 'desired charset', 'utf-8'); 
    
  3. iconv()

    $iduser   = iconv('utf-8', 'desired charset', $iduser); 
    $nome   = iconv('utf-8', 'desired charset', $nome); 
    $data   = iconv('utf-8', 'desired charset', $data); 
    $hora   = iconv('utf-8', 'desired charset', $hora); 
    $mensagem  = iconv('utf-8', 'desired charset', $mensagem); 
    $latitude  = iconv('utf-8', 'desired charset', $latitude); 
    $longitude  = iconv('utf-8', 'desired charset', $longitude); 
    

最後に、クライアントに応答を返すときは、ASCII以外の文字が含まれているときにテキストをエンコードする必要があります。

header($_SERVER["SERVER_PROTOCOL"] . " 200 OK"); 
header('Content-Type: text/plain; charset="utf-8"'); 

if ($imagem != "none") 
{ 
    ... 
    if (mysqli_affected_rows($mysqli) > 0) 
     print utf8_encode("Sucesso!"); 
    else 
     print utf8_encode("Não foi possível inserir o registro"); 
} 
else 
    print utf8_encode("Não á foi possível carregar a imagem."); 
+0

行われた変更が、問題はまだそこにある。また、クライアントは、その符号化に使用されている文字セットを知らせるためにheader()を使用する必要があります。 – wordermorr

+0

@wordermorrどのバージョンのDelphiとIndyを使用していますか? –

+0

Delphi Seattle and Indy 10.6.2.5298 – wordermorr

関連する問題