POSTデータをURLエンコードする必要がありますか?


122

データを外部APIにPOSTしています(必要に応じて、PHPを使用しています)。

渡すPOST変数をURLエンコードする必要がありますか?

または、GETデータのみをURLエンコードする必要がありますか?

ありがとう!

更新:関連する場合に備えて、これは私のPHPです。

$fields = array(
    'mediaupload'=>$file_field,
    'username'=>urlencode($_POST["username"]),
    'password'=>urlencode($_POST["password"]),
    'latitude'=>urlencode($_POST["latitude"]),
    'longitude'=>urlencode($_POST["longitude"]),
    'datetime'=>urlencode($_POST["datetime"]),
    'category'=>urlencode($_POST["category"]),
    'metacategory'=>urlencode($_POST["metacategory"]),
    'caption'=>($_POST["description"])
);
$fields_string = http_build_query($fields);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL,$url);
curl_setopt($ch,CURLOPT_POST,count($fields));
curl_setopt($ch,CURLOPT_POSTFIELDS,$fields);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$response = curl_exec($ch);

1
これは参照用のAPIです。cycletreets.net / api-期待するものを指定していないようです。
リチャード

回答:


136

一般的な回答

あなたの質問への一般的な答えは、それは依存するということです。そして、あなたはあなたの "Content-Type"がHTTPヘッダーに何であるかを指定することによって決定することになります。

「application / x-www-form-urlencoded」の値は、POSTボディをGETパラメータ文字列と同様にURLエンコードする必要があることを意味します。「multipart / form-data」の値は、コンテンツをエンコードするURLではなく、コンテンツ区切り文字を使用することを意味します。

詳しい情報が必要な場合は、この回答にさらに詳しい説明があります。


具体的な回答

使用しているPHPライブラリ(CURL)に固有の回答については、こちらのドキュメントをご覧ください

関連情報は次のとおりです。

CURLOPT_POST

通常のHTTP POSTを実行する場合はTRUE。このPOSTは通常のapplication / x-www-form-urlencodedであり、HTMLフォームで最も一般的に使用されます。

CURLOPT_POSTFIELDS

HTTP "POST"操作で送信する完全なデータ。ファイルを投稿するには、ファイル名の前に@を付け、フルパスを使用します。ファイルタイプは、ファイル名の後に「; type = mimetype」という形式のタイプを付けて明示的に指定できます。このパラメーターは、 'para1 = val1&para2 = val2&...'のようなURLエンコードされた文字列として、またはフィールド名をキーとして、フィールドデータを値として持つ配列として渡すことができます。値が配列の場合、Content-Typeヘッダーはmultipart / form-dataに設定されます。PHP 5.2.0以降、ファイルが@プレフィックス付きでこのオプションに渡される場合、値は配列でなければなりません。


9

@DougWはこの質問に明確に回答していますが、ここでもDougのポイントを説明するためにここにいくつかのコードを追加したいと思います。(そして上記のコードのエラーを修正してください)

解決策1:POSTデータをcontent-typeヘッダー:application / x-www-form-urlencodedでURLエンコードします。

注:$ _POST []フィールドを1つずつurlencodeする必要はありません。http_build_query()関数はurlencodingジョブを適切に実行できます。

$fields = array(
    'mediaupload'=>$file_field,
    'username'=>$_POST["username"],
    'password'=>$_POST["password"],
    'latitude'=>$_POST["latitude"],
    'longitude'=>$_POST["longitude"],
    'datetime'=>$_POST["datetime"],
    'category'=>$_POST["category"],
    'metacategory'=>$_POST["metacategory"],
    'caption'=>$_POST["description"]
);

$fields_string = http_build_query($fields);

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL,$url);
curl_setopt($ch, CURLOPT_POST,1);
curl_setopt($ch, CURLOPT_POSTFIELDS,$fields_string);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$response = curl_exec($ch);

解決策2:Content-Typeヘッダーがmultipart / form-dataに設定される一方で、URLエンコードなしで配列を投稿データとして直接渡します。

$fields = array(
        'mediaupload'=>$file_field,
        'username'=>$_POST["username"],
        'password'=>$_POST["password"],
        'latitude'=>$_POST["latitude"],
        'longitude'=>$_POST["longitude"],
        'datetime'=>$_POST["datetime"],
        'category'=>$_POST["category"],
        'metacategory'=>$_POST["metacategory"],
        'caption'=>$_POST["description"]
    );

    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL,$url);
    curl_setopt($ch, CURLOPT_POST,1);
    curl_setopt($ch, CURLOPT_POSTFIELDS,$fields);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    $response = curl_exec($ch);

両方のコードスニペットは機能しますが、使用するHTTPヘッダーと本文は異なります。


2

curlはデータをエンコードし、生のフィールドデータをfields配列にドロップして、「実行」するように指示します。


1
カールポストデータを送信した後、ターゲットASP Webページがエラーページにリダイレクトするphp curlスクリプトを修正するのに何時間も費やしましたが、その理由を理解できませんでした。次に、投稿データをURLエンコードした後、それが機能し、期待した結果が得られました。
ロビ2014年

1
配列かどうかを調べ、curlによって自動的にURLエンコードされます。文字列として渡される場合は、最初にurlencodeする必要があります。
ロビ、2014年

2

上記の投稿では、URLエンコーディングとその仕組みに関する質問に回答していますが、元の質問は「POSTデータをURLエンコードする必要がありますか?」でした。答えられていません。

最近のURLエンコーディングの経験から、質問をさらに広げたいと思います。「GET HTTPメソッドと同じように、POSTデータをURLエンコードする必要があります。通常、ブラウザ上のHTMLフォームに入力、送信、または情報を取得した場合、ブラウザはURLエンコーディングを実行しますが、アプリケーションがWebサービスを公開し、データに対してURLエンコードを行う消費者は、POST HTTPメソッドを使用してURLエンコードを行うことがアーキテクチャ上および技術的に正しいですか?」

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.