Я пытаюсь отправить POST-запрос на вход в мой сервер PHP/MySQL из приложения Android, и по какой-то причине мое PHP-приложение не видит POST-запрос от Android. Я проверил раздел Network Profiler в Android Studio и вижу, что он отправляет запрос POST, но каждый раз, когда я отправляю запрос, приложение получает «Неверный метод запроса». Ответ JSON у меня настроен.
Я пробовал каждую итерацию каждого возможного решения, которое я мог придумать, чтобы заставить это работать, и я понятия не имею, что мне не хватает. Я опубликую как код Android, так и код PHP, чтобы кто-нибудь мог, надеюсь, указать мне правильное направление того, что я здесь делаю неправильно.
Я создал очень простую веб-форму на своем сервере для проверки данных для входа, и она может прекрасно видеть запросы POST из другого PHP-скрипта. Однако проблема возникает, когда Android пытается выполнить POST для сценария — по какой-то причине приложение не распознает то, что Android отправляет в виде POST-запроса.
Это вся моя активность «doInBackground» в асинхронной части моего приложения для Android.
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 при попытке входа в систему из приложения:
В строке 9 PHP-скрипта я использую if ($_SERVER['REQUEST_METHOD'] == "POST"){, поэтому я проверяю, является ли запрос POST-запросом из приложения Android. Android показывает, что отправляет запрос POST, но PHP по какой-то причине не интерпретирует его как таковой. Это похоже на то, что PHP-скрипт просто полностью отключается и не замечает, что POST попадает в него.






Вы используете метод POST для передачи учетных данных на стороне android. В то время как на стороне php вы сначала проверяете, является ли это запросом POST, а затем пытаетесь получить параметры с запросом GET.
Использовать этот:
if ($_SERVER['REQUEST_METHOD'] == "POST"){
$username = $_POST["username"];
$password = md5($_POST["password"]);
}
Что ж, «действие» на самом деле является параметром, который я передаю в самом URL-адресе, чтобы скрипт API знал, что я вхожу в систему. У меня есть еще один раздел в сценарии api.php для «регистрации», поэтому URL-адрес, который я отправляю данные to это "api.php?action=login".
Спасибо за попытку, но это все равно не помогло. Я пошел дальше и изменил свой сценарий в приложении PHP, чтобы проверить переменную POST «действие», а в самом приложении я изменил URL-адрес, чтобы просто вызывать «api.php» вместо «api.php?action=login». Однако он все еще не работает. Я даже зашел в скрипт api.php и сделал: php foreach($_POST as $key => $val) { $response["message"] = $key . ": " . $val; } В самом начале файла, перед вызовом любого метода request_method, просто чтобы поймать любые переменные $_POST, и он ничего не печатал в приложении.
Я ценю вашу попытку помочь, но это не решило проблему, даже после того, как я внес изменения. Я думаю, что это может быть что-то на стороне Android, например, он не отправляет правильные заголовки, или, может быть, моя сторона PHP не слушает правильные заголовки или что-то в этом роде... Я понятия не имею.
После долгих копаний я, наконец, решил проблему. У меня есть файл .htaccess в корне моего веб-сайта (это приложение для Android использует субдомен). Этот файл .htaccess перенаправлял ВЕСЬ трафик на часть https://www моего веб-сайта, которая по какой-то причине также перехватывала мой субдомен.
Я обнаружил это, просматривая журналы Apache на моем сервере для поддомена и заметив, что ответ был 301, поэтому я знал, что что-то не так и меня куда-то перенаправляют. После отключения перенаправления .htaccess я наконец получил ответ в приложении, которое искал.
Извините за беспокойство, и, надеюсь, это может помочь кому-то еще!
Если ваш сервер REQUEST_METHOD дает сбой, то чему равно
$_SERVER['REQUEST_METHOD']? Какой ответ возвращается?