Я провел много исследований и не мог найти способ справиться с этим. Я пытаюсь выполнить вызов jQuery ajax с https-сервера на https-сервер locahost, на котором работает причал, с настраиваемым самоподписанным сертификатом. Моя проблема в том, что я не могу определить, является ли ответ отказом в соединении или небезопасным ответом (из-за отсутствия принятия сертификата). Есть ли способ определить разницу между обоими сценариями? В обоих случаях responseText
, и statusCode
всегда одинаковы, хотя в консоли Chrome я вижу разницу:
net::ERR_INSECURE_RESPONSE
net::ERR_CONNECTION_REFUSED
responseText
всегда "" и statusCode
всегда "0" в обоих случаях.
Мой вопрос: как я могу определить, произошел ли сбой вызова jQuery ajax из-за ERR_INSECURE_RESPONSE
или из-за ERR_CONNECTION_REFUSED
?
После принятия сертификата все работает нормально, но я хочу знать, выключен ли локальный сервер или он работает, но сертификат еще не принят.
$.ajax({
type: 'GET',
url: "https://localhost/custom/server/",
dataType: "json",
async: true,
success: function (response) {
//do something
},
error: function (xhr, textStatus, errorThrown) {
console.log(xhr, textStatus, errorThrown); //always the same for refused and insecure responses.
}
});
Даже выполняя запрос вручную, я получаю тот же результат:
var request = new XMLHttpRequest();
request.open('GET', "https://localhost/custom/server/", true);
request.onload = function () {
console.log(request.responseText);
};
request.onerror = function () {
console.log(request.responseText);
};
request.send();
источник
function (xhr, status, msg) {...
Я сомневаюсь, что они это сделают, но попробовать стоит.Ответы:
Невозможно отличить его от новейших веб-браузеров.
Спецификация W3C:
Как вы можете прочитать, сетевые ошибки не включают HTTP-ответ, содержащий ошибки, поэтому вы всегда будете получать 0 в качестве кода состояния и "" в качестве ошибки.
Источник
Примечание . Следующие примеры были сделаны с использованием Google Chrome версии 43.0.2357.130 и в среде, которую я создал для имитации OP one. Код для настройки находится внизу ответа.
Я думал, что подход Чтобы обойти это было бы сделать вторичный запрос через HTTP вместо HTTPS, как этот ответ но я вспомнил, что это невозможно из-за того, что более новые версии браузеров блокируют смешанный контент.
Это означает, что веб-браузер не будет разрешать запросы через HTTP, если вы используете HTTPS, и наоборот.
Так было несколько лет назад, но более старые версии веб-браузеров, такие как Mozilla Firefox ниже 23 версии, допускают это.
Свидетельства об этом:
Выполнение HTTP-запроса от HTTPS с использованием консоли Web Broser
приведет к следующей ошибке:
Та же ошибка появится в консоли браузера, если вы попытаетесь сделать это другими способами, например, добавив iframe.
Использование Socket-соединения также было отправлено в качестве ответа , я был уверен, что результат будет таким же / похожим, но я попробовал.
Попытка открыть сокет-соединение от Web Broswer с использованием HTTPS к незащищенной конечной точке сокета закончится ошибками смешанного содержимого.
Затем я попытался подключиться к конечной точке wss, посмотрите, могу ли я прочитать некоторую информацию об ошибках сетевого подключения:
Выполнение приведенного выше фрагмента с выключенным сервером приводит к:
Выполнение приведенного выше фрагмента с включенным сервером
Но опять же, ошибка, выводимая на консоль "функцией onerror", не имеет подсказки, чтобы отличить одну ошибку от другой.
Использование прокси, как предлагает этот ответ, может работать, но только в том случае, если «целевой» сервер имеет открытый доступ.
Здесь этого не было, поэтому попытка реализовать прокси в этом сценарии приведет Нас к той же проблеме.
Код для создания HTTPS-сервера Node.js :
Я создал два HTTPS-сервера Nodejs, которые используют самозаверяющие сертификаты:
targetServer.js:
applicationServer.js:
Чтобы он работал, вам необходимо установить Nodejs, необходимо создать отдельные сертификаты для каждого сервера и сохранить их в папках certs и certs2 соответственно.
Чтобы запустить его, просто выполните
node applicationServer.js
иnode targetServer.js
в терминале (пример ubuntu).источник
На данный момент: нет возможности различать это событие между браузерами. Поскольку браузеры не предоставляют события для доступа разработчиков. (Июль 2015 г.)
Этот ответ просто пытается предоставить идеи для потенциального, хакерского и неполного решения.
Отказ от ответственности: этот ответ является неполным, поскольку он не полностью решает проблемы OP (из-за политики перекрестного происхождения). Однако сама идея имеет некоторые достоинства, которые далее расширяются: @artur grzesiak здесь , используя прокси и ajax.
После небольшого исследования, похоже, не существует какой-либо формы проверки ошибок для разницы между отказом в соединении и небезопасным ответом, по крайней мере, в том, что касается javascript, обеспечивающего ответ для разницы между ними.
По общему мнению, в моих исследованиях SSL-сертификаты обрабатываются браузером, поэтому до тех пор, пока самоподписанный сертификат не будет принят пользователем, браузер блокирует все запросы, включая запросы на код состояния. Браузер может (если он закодирован) отправить обратно свой собственный код состояния для незащищенного ответа, но это на самом деле ничего не помогает, и даже тогда у вас будут проблемы с совместимостью браузера (chrome / firefox / IE имеют разные стандарты. .. снова)
Поскольку ваш первоначальный вопрос заключался в проверке статуса вашего сервера между включением и наличием непринятого сертификата, не могли бы вы сделать такой стандартный HTTP-запрос?
Конечно, для этого требуется дополнительный запрос на проверку подключения к серверу, но он должен выполнять свою работу путем исключения. Тем не менее, все еще кажется хакерским, и я не большой поклонник двойного запроса.
источник
Ответ @ Schultzie довольно близок, но ясно
http
- в целом - не будет работать изhttps
в среде браузера.Однако вы можете использовать промежуточный сервер (прокси) для отправки запроса от вашего имени. Прокси-сервер должен позволять либо пересылать
http
запрос изhttps
источника, либо загружать контент из самоподписанных источников. .Наличие собственного сервера с надлежащим сертификатом в вашем случае, вероятно, является излишним, поскольку вы можете использовать этот параметр вместо машины с самоподписанным сертификатом, но существует множество анонимных открытых прокси-сервисов. .
На ум приходят два подхода:
.parentWindow
. Если ваше окно получило сообщение, вы можете быть уверены, что сервер запущен (точнее, работал на долю секунды раньше).Если вас интересует только ваша локальная среда, вы можете попробовать запустить хром с
--disable-web-security
флагом.Другое предложение: вы пытались программно загрузить изображение, чтобы узнать, есть ли там дополнительная информация?
источник
Ознакомьтесь с jQuery.ajaxError () Взято из ссылки: jQuery AJAX Error Handling (HTTP Status Codes) Он улавливает глобальные ошибки Ajax, которые вы можете обрабатывать любым количеством способов через HTTP или HTTPS:
источник
К сожалению, современный браузер XHR API не предоставляет явных указаний на то, когда браузер отказывается подключаться из-за «небезопасного ответа», а также когда он не доверяет сертификату HTTP / SSL веб-сайта.
Но есть способы обойти эту проблему.
Одно из решений, которое я придумал, чтобы определить, когда браузер не доверяет сертификату HTTP / SSL, состоит в том, чтобы сначала определить, произошла ли ошибка XHR (например, с помощью
error()
обратного вызова jQuery ), а затем проверить, является ли вызов XHR на https : // 'URL, а затем проверьте, что XHRreadyState
равен 0, что означает, что соединение XHR даже не было открыто (что происходит, когда браузеру не нравится сертификат).Вот код, в котором я это делаю: https://github.com/maratbn/RainbowPayPress/blob/e9e9472a36ced747a0f9e5ca9fa7d96959aeaf8a/rainbowpaypress/js/le_requirejs/public/model_info__transactions_details.
источник
Я не думаю, что в настоящее время есть способ обнаружить эти сообщения об ошибках, но вы можете взломать сервер, например nginx, перед вашим сервером приложений, так что если сервер приложений не работает, вы получите плохой ошибка шлюза от nginx с
502
кодом состояния, который вы можете обнаружить в JS. В противном случае, если сертификат недействителен, вы все равно получите ту же общую ошибку сstatusCode = 0
.источник