我需要对POST数据进行URL编码吗?

136

我正在使用PHP向外部API发送POST数据。

我应该对传递的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,供参考:http://www.cyclestreets.net/api/ - 它似乎没有指定它期望什么。 - Richard
4个回答

155

一般回答

你的问题的一般回答是,它取决于你在HTTP头中指定的“Content-Type”。

“application/x-www-form-urlencoded”的值意味着您的POST主体需要像GET参数字符串一样进行URL编码。 “multipart/form-data”的值意味着您将使用内容分隔符而不是对内容进行url编码。

如果您想要更多信息,请查看这个答案


具体回答

针对您正在使用的PHP库(CURL)的具体答案,您应该阅读此处的文档

以下是相关信息:

CURLOPT_POST

设置为TRUE则执行常规HTTP POST请求。 这个POST请求是常规的application/x-www-form-urlencoded类型,最常用于HTML表单。

CURLOPT_POSTFIELDS

发起一个HTTP“POST”操作所需完整数据。如果要提交文件,则需要在文件名前面加上@并使用完整路径。文件类型可以通过在格式“;type=mimetype”中在文件名后面指定来显式地指定。此参数可以作为urlencoded字符串传递,例如'para1=val1&para2=val2&...',也可以作为数组传递,其中字段名称作为键,字段数据作为值。如果值是一个数组,则Content-Type头将设置为multipart/form-data。从PHP 5.2.0开始,如果要使用@前缀将文件传递给此选项,则value必须是一个数组。


13

@DougW已经清楚地回答了这个问题,但我仍然想在这里添加一些代码来解释Doug的观点。(并更正上面的代码中的错误)

解决方案1:使用内容类型头:application/x-www-form-urlencoded对POST数据进行URL编码。

注意:您不需要一个一个地urlencode $_POST[]字段,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:直接将数组作为POST数据传递,不需要进行URL编码,同时Content-Type标头将被设置为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);

这两个代码片段都有效,但使用不同的HTTP标头和正文。


1
http_build_query() function can do the urlencoding job nicely. Thanks this is what i was looking for for days .` - Salem

2

curl会为你编码数据,只需将原始字段数据放入fields数组中并让它“运行”。


2
我花了几个小时来修复一个 PHP Curl 脚本,其中目标 ASP 网页在发送 Curl POST 数据后将我重定向到错误页面,而我无法弄清楚原因。然后,在对 POST 数据进行 URL 编码之后,它开始工作并且我得到了期望的结果。 - Robi
2
如果它是数组,则curl会自动进行url编码。如果作为字符串传递,则需要先进行urlencode。 - Robi

2
上面的帖子回答了与URL编码和其工作方式相关的问题,但原始问题是“我应该对POST数据进行URL编码吗?”,这个问题没有得到回答。
根据我的最近经验,我想进一步扩展这个问题。在使用POST HTTP方法时,是否应该像GET HTTP方法一样对POST数据进行URL编码呢?通常,如果HTML表单在浏览器上填写、提交和/或获取一些信息,浏览器会进行URL编码,但如果一个应用程序暴露了一个Web服务,并期望使用者对数据进行URL编码,那么在POST HTTP方法中进行URL编码在技术上和架构上是否正确?

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接