PHP无法识别来自Android HttpsURLConnection的POST

时间:2019-07-16 15:31:35

标签: php android

我正在尝试从Android应用程序向我的PHP / MySQL后端发送登录POST请求,由于某种原因,我的PHP应用程序没有看到来自Android的POST请求。我已经检查了Android Studio的Network Profiler部分,可以看到它正在发送POST请求,但是每次发送请求时,该应用都会收到“请求方法不正确”。我已经设置了JSON响应。

我尝试了所有可能的解决方案的每一次迭代,以使其能够正常工作,但我不知道自己缺少什么。我将同时发布Android代码和PHP代码,以便希望某处的人可以指出我在这里做错了什么的正确方向。

我在服务器上创建了一个非常简单的Web表单来测试登录数据,它可以看到来自另一个PHP脚本的POST请求就可以了。但是,当Android尝试将POST发送到脚本时,就会出现问题-由于某种原因,应用无法识别Android作为POST请求发送的内容。

这是我整个Android应用程序“异步”部分的“ doInBackground”活动。

String action = params[0];

        if (action.equals("login")) {
            // Url to login at
            String postUrl = Urls.URL_LOGIN;

            // Username and password from login form
            String username = params[1];
            String password = params[2];

            try {
                URL url = new URL(postUrl);
                boolean redirect = false;

                do {
                    redirect = false;

                    String urlParameters = URLEncoder.encode("username", "UTF-8") + "=" + URLEncoder.encode(username, "UTF-8") + "&" + URLEncoder.encode("password", "UTF-8") + "=" + URLEncoder.encode(password, "UTF-8");

                    byte[] postData = urlParameters.getBytes(StandardCharsets.UTF_8);
                    int postDataLength = postData.length;

                    HttpURLConnection conn = (HttpURLConnection) url.openConnection();
                    conn.setReadTimeout(20000);
                    conn.setConnectTimeout(20000);
                    conn.setRequestMethod("POST");
                    conn.setDoOutput(true);
                    conn.setDoInput(true);
                    conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded;charset=UTF-8");
                    conn.setRequestProperty("Content-Length", Integer.toString(postDataLength));
                    conn.setRequestProperty("Accept", "application/json");
                    conn.setUseCaches(false);

                    OutputStream os = conn.getOutputStream();
                    OutputStreamWriter osW = new OutputStreamWriter(os, "UTF-8");
                    BufferedWriter writer = new BufferedWriter(osW);

                    writer.write(urlParameters);
                    writer.flush();
                    writer.close();
                    os.close();

                    int responseCode = conn.getResponseCode();

                    if (responseCode == HttpsURLConnection.HTTP_OK) {
                        InputStream inputStream = conn.getInputStream();
                        BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream, "ISO-8859-1"));

                        StringBuilder sb = new StringBuilder();
                        String json;

                        while ((json = bufferedReader.readLine()) != null) {
                            sb.append(json + "\n");
                        }

                        bufferedReader.close();
                        inputStream.close();

                        conn.disconnect();

                        return sb.toString().trim();
                    } else {
                        redirect = true;
                        Log.d("*** RANDOM CHAT ***", "HTTP Response Code: " + responseCode);

                        return null;
                    }
                } while (redirect);
            } catch (MalformedURLException e) {
                return null;
            } catch (IOException e) {
                return null;
            }
        }

        return null;

这是我整个PHP应用程序,用于监听POST。

header('Content-Type: application/json');

require_once("inc.db.php");
require_once("inc.fx.php");

$response = array();

if($_SERVER['REQUEST_METHOD'] == "POST"){
    if(isset($_GET["action"]) && $_GET["action"] == "login") {
        if(is_valid(array('username','password'))) {
            $username = $_POST["username"];
            $password = md5($_POST["password"]);

            if(count_db("users",array("username","password","banned"),array($username,$password,0))["data"] > 0) {
                $response = get_db("users",array("username","password"),array($username,$password));
            } else {
                $response["success"] = false;
                $response["data"] = "Invalid login information. Username: " . $username . ", Password: " . $password;
            }
        } else {
            $response["success"] = false;
            $response["data"] = "Username and password required for login. Username: " . $_POST["username"] .", Password: " . $_POST["password"];
        }
    } elseif(isset($_GET["action"]) && $_GET["action"] == "register") {
        if(is_valid(array('username','password'))) {
            $username = $_POST["username"];
            $email = $_POST["email"];
            $password = md5($_POST["password"]);

            if((count_db("users",array("username"),array($username))["data"] <= 0) && (count_db("users",array("email"),array($email))["data"] <= 0)) {
                if(insert_db("users",array("username","email","password"),array($username,$email,$password))) {
                    $response = get_db("users",array("username"),array($username));
                } else {
                    $response['success'] = false;
                    $response['data'] = "Unable to create user.";
                }
            } else {
                $response["success"] = false;
                $response["data"] = "Username or email exists.";
            }
        } else {
            $response["success"] = false;
            $response["data"] = "Username, email, and password required for registration.";
        }
    } else {
        $response['success'] = false;
        $response['data'] = "No server action specified.";
    }
} else {
    $response['success'] = false;
    $response['data'] = "Request method incorrect.";
}

echo json_encode($response);

我希望最基本的服务器REQUEST_METHOD检查能够通过,因为我正在发送POST,但事实并非如此。一旦检查通过,我就假定PHP代码在读取POST请求的用户名和密码并将有效响应发送回应用程序供我稍后处理时将没有问题。

以防万一有人希望看到它,以下是尝试从应用程序登录时的Network Profiler信息:

Android Network Profiler

2 个答案:

答案 0 :(得分:0)

您正在使用POST方法在android端传递登录凭证。在php端,您首先要检查它是否是POST请求,然后尝试通过GET请求获取参数。

使用此:

if($_SERVER['REQUEST_METHOD'] == "POST"){
   $username = $_POST["username"];
   $password = md5($_POST["password"]);
}

答案 1 :(得分:-1)

经过大量挖掘,我终于解决了该问题。我在网站的根目录下有一个.htaccess文件(此Android应用正在访问子域)。该.htaccess文件将所有流量重定向到我网站的https://www部分,由于某种原因,该流量也捕获了我的子域。

我是通过查看服务器上该子域的apache日志并注意到响应为301来找到此消息的,所以我知道出了点问题并将其重定向到某处。禁用.htaccess重定向后,我终于在想要的应用程序中收到了响应。

很抱歉遇到麻烦,希望这可以帮助其他人!