Http Post 未发布数据

发布于 2024-12-01 23:34:01 字数 1969 浏览 0 评论 0原文

我正在尝试使用套接字从 Java 客户端发布一些数据。它与运行 php 代码的本地主机进行通信,该代码只是吐出发送给它的 post 参数。

这是 Java 客户端:

 public static void main(String[] args) throws Exception {

       Socket socket = new Socket("localhost", 8888);
       String reqStr = "testString";

        String urlParameters = URLEncoder.encode("myparam="+reqStr, "UTF-8");
        System.out.println("Params: " + urlParameters);

        try {
            Writer out = new OutputStreamWriter(socket.getOutputStream(), "UTF-8");
            out.write("POST /post3.php HTTP/1.1\r\n");  
            out.write("Host: localhost:8888\r\n"); 
            out.write("Content-Length: " + Integer.toString(urlParameters.getBytes().length) + "\r\n");
            out.write("Content-Type: text/html\r\n\n");
            out.write(urlParameters);  
            out.write("\r\n");  
            out.flush();

            InputStream inputstream = socket.getInputStream();
            InputStreamReader inputstreamreader = new InputStreamReader(inputstream);
            BufferedReader bufferedreader = new BufferedReader(inputstreamreader);

            String string = null;
            while ((string = bufferedreader.readLine()) != null) {
               System.out.println("Received " + string);
            }

       } catch(Exception e) {
           e.printStackTrace();
       } finally {
         socket.close(); 
       }
 }

这是 post3.php 的样子:

<?php

$post = $_REQUEST;

echo print_r($post, true);
?>

我期望看到一个数组 (myparams => "testString") 作为响应。但它没有将 post args 传递给服务器。 以下是输出:

Received HTTP/1.1 200 OK
Received Date: Thu, 25 Aug 2011 20:25:56 GMT
Received Server: Apache/2.2.17 (Unix) mod_ssl/2.2.17 OpenSSL/0.9.8r DAV/2 PHP/5.3.6
Received X-Powered-By: PHP/5.3.6
Received Content-Length: 10
Received Content-Type: text/html
Received 
Received Array
Received (
Received )

仅供参考,此设置适用于 GET 请求。

知道这是怎么回事吗?

I'm trying to post some data from a Java client using sockets. It talks to localhost running php code, that simply spits out the post params sent to it.

Here is Java Client:

 public static void main(String[] args) throws Exception {

       Socket socket = new Socket("localhost", 8888);
       String reqStr = "testString";

        String urlParameters = URLEncoder.encode("myparam="+reqStr, "UTF-8");
        System.out.println("Params: " + urlParameters);

        try {
            Writer out = new OutputStreamWriter(socket.getOutputStream(), "UTF-8");
            out.write("POST /post3.php HTTP/1.1\r\n");  
            out.write("Host: localhost:8888\r\n"); 
            out.write("Content-Length: " + Integer.toString(urlParameters.getBytes().length) + "\r\n");
            out.write("Content-Type: text/html\r\n\n");
            out.write(urlParameters);  
            out.write("\r\n");  
            out.flush();

            InputStream inputstream = socket.getInputStream();
            InputStreamReader inputstreamreader = new InputStreamReader(inputstream);
            BufferedReader bufferedreader = new BufferedReader(inputstreamreader);

            String string = null;
            while ((string = bufferedreader.readLine()) != null) {
               System.out.println("Received " + string);
            }

       } catch(Exception e) {
           e.printStackTrace();
       } finally {
         socket.close(); 
       }
 }

This is how post3.php looks like:

<?php

$post = $_REQUEST;

echo print_r($post, true);
?>

I expect to see an array (myparams => "testString") as the response. But its not passing post args to server.
Here is output:

Received HTTP/1.1 200 OK
Received Date: Thu, 25 Aug 2011 20:25:56 GMT
Received Server: Apache/2.2.17 (Unix) mod_ssl/2.2.17 OpenSSL/0.9.8r DAV/2 PHP/5.3.6
Received X-Powered-By: PHP/5.3.6
Received Content-Length: 10
Received Content-Type: text/html
Received 
Received Array
Received (
Received )

Just a FYI, this setup works for GET requests.

Any idea whats going on here?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

蹲墙角沉默 2024-12-08 23:34:01

正如 Jochen 和 chesles 正确指出的那样,您使用了错误的 Content-Type: 标头 - 它确实应该是 application/x-www-form-urlencoded。然而,还有其他几个问题......

  • 最后一个标题应该通过标题和正文之间的空行与正文分开。这应该是一个完整的 CRLF (\r\n),在您的代码中它只是一个新行 (\n)。这是彻底的协议违规,我有点惊讶你没有从服务器返回一个 400 Bad Request,尽管 Apache 在这方面可以相当宽容。
  • 您应该指定Connection: close以确保您不会一直打开套接字,服务器将在请求完成后立即关闭连接。
  • 不需要最终的 CRLF 序列。 PHP 足够智能,可以自行解决这个问题,但其他服务器语言和实现可能不会...

如果您正在使用任何原始状态的标准化协议,您应该始终至少从扫描 RFC

另外,请了解保护您的 Apache 安装...

As Jochen and chesles rightly point out, you are using the wrong Content-Type: header - it should indeed be application/x-www-form-urlencoded. However there are several other issues as well...

  • The last header should be seperated from the body by a blank line between the headers and the body. This should be a complete CRLF (\r\n), in your code it is just a new line (\n). This is an outright protocol violation and I'm a little surprised you haven't just got a 400 Bad Request back from the server, although Apache can be quite forgiving in this respect.
  • You should specify Connection: close to ensure that you are not left hanging around with open sockets, the server will close the connection as soon as the request is complete.
  • The final CRLF sequence is not required. PHP is intelligent enough to sort this out by itself, but other server languages and implementations may not be...

If you are working with any standardised protocol in it's raw state, you should always start by at least scanning over the RFC.

Also, please learn to secure your Apache installs...

零度℉ 2024-12-08 23:34:01

看起来您正在尝试以 application/x-www-form-urlencoded 格式发送数据,但您将 Content-Type 设置为 text/html。

It looks like you are trying to send data in application/x-www-form-urlencoded format, but you are setting the Content-Type to text/html.

纸伞微斜 2024-12-08 23:34:01

代替使用

out.write("Content-Type: application/x-www-form-urlencoded\n\n");

。正如此页面所述:

Content-Length 和 Content-Type 标头至关重要,因为它们告诉 Web 服务器需要多少字节的数据以及由 MIME 类型标识的数据类型。

要发送表单数据,即格式为 key=value&key2=value2 的数据,请使用 application/x-www-form-urlencodedvalue 是否包含 HTML、XML 或其他数据并不重要;服务器将为您解释它,您将能够像平常一样在 PHP 端的 $_POST$_REQUEST 数组中检索数据。

或者,您可以使用适当的 Content-Type 标头以原始 HTML、XML 等形式发送数据,但随后必须 通过读取特殊文件 php://input 在 PHP 中手动检索数据

<?php
echo file_get_contents("php://input");
?>

顺便说一句,如果您如果将其用于任何足够复杂的事情,我强烈建议使用 HTTP客户端库,例如 HTTPClient

Use

out.write("Content-Type: application/x-www-form-urlencoded\n\n");

instead. As this page states:

The Content-Length and Content-Type headers are critical because they tell the web server how many bytes of data to expect, and what kind, identified by a MIME type.

For sending form data, i.e. data in the format key=value&key2=value2 use application/x-www-form-urlencoded. It doesn't matter if the value contains HTML, XML, or other data; the server will interpret it for you and you'll be able to retrieve the data as usual in the $_POST or $_REQUEST arrays on the PHP end.

Alternatively, you can send your data as raw HTML, XML, etc. using the appropriate Content-Type header, but you then have to retrieve the data manually in PHP by reading the special file php://input:

<?php
echo file_get_contents("php://input");
?>

As an aside, if you're using this for anything sufficiently complex, I would strongly recommend the use of an HTTP client library like HTTPClient.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文