Devo codificar dados POST por URL?

122

Estou postando dados em uma API externa (usando PHP, se for relevante).

Devo codificar por URL as variáveis ​​POST que eu passo?

Ou preciso codificar dados GET apenas por URL?

Obrigado!

UPDATE: Este é o meu PHP, caso seja relevante:

$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);
Richard
fonte
1
Esta é a API, para referência: cyclestreets.net/api - parece não especificar o que espera.
Richard

Respostas:

136

Resposta Geral

A resposta geral para sua pergunta é que depende. E você decide, especificando qual é o seu "Tipo de Conteúdo" nos cabeçalhos HTTP.

Um valor de "application / x-www-form-urlencoded" significa que seu corpo do POST precisará ser codificado em URL como uma sequência de parâmetros GET. Um valor "multipart / form-data" significa que você usará delimitadores de conteúdo e NÃO codificará o URL.

Esta resposta tem uma explicação muito mais completa se você quiser obter mais informações.


Resposta específica

Para uma resposta específica para as bibliotecas PHP que você está usando (CURL), você deve ler a documentação aqui .

Aqui estão as informações relevantes:

CURLOPT_POST

TRUE para executar um HTTP POST normal. Este POST é o tipo application / x-www-form-urlencoded normal, mais comumente usado por formulários HTML.

CURLOPT_POSTFIELDS

Os dados completos para postar em uma operação HTTP "POST". Para postar um arquivo, adicione um nome de arquivo com @ e use o caminho completo. O tipo de arquivo pode ser especificado explicitamente seguindo o nome do arquivo com o tipo no formato '; type = mimetype'. Esse parâmetro pode ser passado como uma string codificada em url como 'para1 = val1 & para2 = val2 & ...' ou como uma matriz com o nome do campo como chave e os dados do campo como valor. Se value for uma matriz, o cabeçalho Content-Type será definido como multipart / form-data. A partir do PHP 5.2.0, o valor deve ser uma matriz se os arquivos forem passados ​​para esta opção com o prefixo @.

DougW
fonte
9

O @DougW respondeu claramente a essa pergunta, mas ainda gosto de adicionar alguns códigos aqui para explicar os pontos de Doug. (E corrija erros no código acima)

Solução 1: codifique por URL os dados do POST com um cabeçalho do tipo de conteúdo: application / x-www-form-urlencoded.

Nota: você não precisa urlencode os campos $ _POST [] um por um, a função http_build_query () pode executar bem o trabalho de codificação de 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"]
);

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

Solução 2: passe a matriz diretamente como dados de postagem sem codificação de URL, enquanto o cabeçalho Content-Type será definido como multipart / form-data.

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

Ambos os trechos de código funcionam, mas usando diferentes cabeçalhos e corpos HTTP.

sem céu
fonte
2

O curl codificará os dados para você, basta soltar os dados brutos do campo na matriz de campos e dizer para "ir".

user340140
fonte
1
Passei horas para corrigir um script php curl em que a página ASP de destino está me redirecionando para uma página de erro após o envio de dados de postagem de curl e não consegui descobrir o porquê. Depois de codificar os dados da postagem, o URL funcionou e comecei a obter o resultado esperado.
Robi
1
parece que é array, então ele será codificado automaticamente pelo URL. se for passado como string, primeiro precisamos urlencode.
22414 Robi
2

As postagens acima respondem a perguntas relacionadas à codificação de URL e como ele funciona, mas as perguntas originais eram "Devo codificar por URL os dados do POST?" que não é respondido.

Da minha experiência recente com a codificação de URL, gostaria de estender ainda mais a questão. "Devo codificar por URL os dados POST, o mesmo que o método GET HTTP. Geralmente, os formulários HTML no navegador se forem preenchidos, enviados e / ou GET algumas informações, os navegadores farão a codificação de URL, mas se um aplicativo expuser um serviço da Web e esperar Os consumidores fazem a codificação de URL nos dados. É arquitetônico e tecnicamente correto fazer a codificação de URL com o método HTTP POST? "

Varun
fonte