Как обеспечить вход с URL-адреса не с перенаправленной страницы

У меня есть следующие строки кода, которые собирают исходный код с заданного URL:

URL url = new URL(websiteAddress);
URLConnection connection = url.openConnection(); // throws an IOException
connection.setConnectTimeout(timeoutInMilliseconds);
bufferedReader = new BufferedReader(new InputStreamReader(connection.getInputStream()));

String line;
while ((line = bufferedReader.readLine()) != null) {
 outputString += line;
}

Однако проблема, с которой я столкнулась, заключается в том, что wi-fi hotspots часто перенаправляют вас на страницу, где вы должны нажать "Я согласен". Если вы запустите этот код, прежде чем щелкнуть этот флажок, он будет собирать исходный код со страницы входа в hotspot, а не на страницу.

Я хочу, чтобы у меня был способ проверить, была ли достигнута предполагаемая страница. Я надеялся, что вызов connection.getURL() после создания InputStreamReader покажет мне фактическую веб-страницу, которая была получена, но не такая удача. Как определить, перенаправлен ли целевой URL?

3 ответа

Один из способов - найти какой-либо конкретный элемент вашей web страницы, и если его там нет, вы знаете, что можете быть на какой-то другой странице (возможно, перенаправлены на какую-либо страницу входа).


Единственное, что я могу предложить, - это иметь сервер, на котором вы знаете, что такое ответ, и сначала запросить, чтобы обеспечить возможность подключения по крайней мере к этому серверу. Этого будет (как правило) достаточно для обеспечения полной возможности подключения.

Затем вы можете запросить интересующий вас URL.

Проблема заключается в том, что если компьютер запрашивает страницу на каком-то URL-адресе, то, как работает много горячих точек Wi-Fi, нужно перехватить этот запрос и вернуть страницу. Часто нет подсказки, сформируйте компьютерный POV, чтобы страница была возвращена, а не запрашиваемая страница.


Один из вариантов - вызвать setFollowRedirects(false). По умолчанию соединение будет тихо следовать переадресации и попытаться добраться до страницы, которая возвращает 200 HTTP-ответ. Отключение повторного перенаправления приведет к тому, что ожидаемая страница будет возвращена легче, просто подтвердите, что ответ - 200.

Тем не менее, комментарий @rec стоит учитывать - недостаточно просто проверить код ответа, поскольку существует много разных способов прерывания вашего запроса маршрутизатором, многие из которых не поддаются обнаружению. Например, вредоносный маршрутизатор может перехватить все ваши запросы и изменить ответный контент тонким, но опасным способом - это называется атакой "человек в середине".

По определению вы не можете избежать атак MitM, если вы не можете открыть безопасное и надежное соединение (как правило, HTTPS) между собой и удаленным сайтом, однако, полагая, что вас действительно не интересуют атаки, лучшая тактика - это просто взять данные, которые вы получаете назад можно сломать любым количеством способов, а вместо этого сделать вашу логику выскабливания более надежной для этой возможности.

Я не могу прямо говорить о том, как сделать вашу логику более надежной, не понимая ваш прецедент и проблемы, с которыми вы столкнулись, однако суть заключается в том, чтобы добавлять проверки, где могут возникнуть проблемы, и вызывать исключение, которое вы затем обрабатываете изящно выше стека.

Например, если ваш код:

System.out.println(outputString.subString(outputString.indexOf('A'));

Это не outputString didn't actually have an если у outputString didn't actually have an символ "A". Поэтому проверьте это явно:

int aPos = outputString.indexOf('A');
if (aPos < 0) {
 throw new InvalidParseException("Didn't find an 'A', cannot proceed");
}
System.out.println(outputString.subString(aPos);

И обрабатывайте InvalidParseException везде, где он наиболее InvalidParseException для вашего случая использования.

licensed under cc by-sa 3.0 with attribution.