Как проверить, является ли URL действительным (фактически загружает страницу с контентом) эффективно? - PullRequest
1 голос
/ 18 февраля 2020

ВОПРОС:

Как проверить, является ли URL действительным и действительно ли загружает страницу?

С моим текущим кодом проверяется только код состояния, который означает, что URL-адрес типа http://fsd.com/ будет считаться действительным, хотя он ничего не загружает.

Как проверить, что URL-адрес действительно указывает на веб-сайт, который можно загрузить?


КОД:

$.ajax({
                    url: link,
                    dataType: 'jsonp', 
                    statusCode: {
                        200: function() {
                            console.log( "status code 200 returned");
                            validURL = true;
                        },
                        404: function() {
                            console.log( "status code 404 returned");
                            validURL = false;
                        }
                    },
                    error:function(){
                        console.log("Error");
                    }
                });

РЕДАКТИРОВАТЬ: Под действительным я имею в виду, что страница, наконец, частично загружена ( по крайней мере, загружаются html & css) вместо загрузки навсегда или сбоя без кода состояния 404.

EDIT2: http://fsd.com фактически возвращает 404 сейчас, как и должно ...

EDIT3: Другой пример: https://dsd.com загружает пустую страницу (код состояния 200) и http://dsd.com фактически загружает страницу с контентом (код состояния 200). На моем Node.js бэкенде пакет npm "url-существующие" указывает, что https://dsd.com недопустим, в то время как мой интерфейс с кодом, показанным в моем вопросе, указывает, что это действительный URL. Вот как выглядит код пакета: https://github.com/boblauer/url-exists/blob/master/index.js, но я хотел бы знать, что будет лучшим способом для пользователей SO.

EDIT4:

К сожалению, запрос, предоставленный Addis, по-видимому, заблокирован CORS, который блокирует выполнение остальной части моего кода, в то время как мой исходный запрос не сделал.

$.ajax({
                    type: "HEAD",
                    url: link,
                    dataType: 'jsonp', 
                }).done(function(message,text,response){
                    const size = response.getResponseHeader('Content-Length');
                    const status = response.status;
                    console.log("SIZE: "+size);
                    console.log("STATUS: "+status);
                    if(size > 0 && status == "200") {
                        $("#submitErrorMessage").css("display","none");
                        $('#directoryForm').submit();
                    }
                    else {
                        $("#submitErrorMessage").css("display","block");
                        $("#submitLoading").css("display","none");
                    }
                });

РЕДАКТИРОВАТЬ 5:

Чтобы быть более точным, оба запроса вызывают предупреждение консоли в консоли браузера, указывающее, что ответ был заблокирован из-за CORS, но мой исходный код фактически выполняется полностью, в то время как другой запрос не выполняет добраться до console.log ().

РЕДАКТИРОВАТЬ 6:

$.ajax({
                    async: true,
                    url: link,
                    dataType: 'jsonp', 
                    success: function( data, status, jqxhr ){
                        console.log( "Response data received: ", data );
                        console.log("Response data length: ", data.length);
                        console.log("Response status code: ", status);
                        if (status == "200" && data.length > 0) {
                            $("#submitErrorMessage").css("display","none");
                            $('#directoryForm').submit();
                        }
                        else {
                            $("#submitErrorMessage").css("display","block");
                            $("#submitLoading").css("display","none"); 
                        }

                    },
                    error:function(jqXHR, textStatus, errorThrown){
                        console.log("Error: ", errorThrown);
                    }
                });

Ошибка:

Error:  Error: jQuery34108117853955031047_1582059896271 was not called
    at Function.error (jquery.js:2)
    at e.converters.script json (jquery.js:2)
    at jquery.js:2
    at l (jquery.js:2)
    at HTMLScriptElement.i (jquery.js:2)
    at HTMLScriptElement.dispatch (jquery.js:2)
    at HTMLScriptElement.v.handle (jquery.js:2)

Ответы [ 4 ]

1 голос
/ 18 февраля 2020

Запрос HEAD используется для получения meta-information, содержащегося в заголовках HTTP. Хорошо, что ответ не содержит тела. Это довольно быстро, и на сервере не должно быть никакой тяжелой обработки, чтобы справиться с этим. Это делает его удобным для быстрой проверки состояния.

Метод HEAD идентичен GET, за исключением того, что сервер НЕ ДОЛЖЕН возвращать тело сообщения в ответе. Метаинформация, содержащаяся в заголовках HTTP в ответ на запрос HEAD, ДОЛЖНА быть идентична информации, отправленной в ответ на запрос GET. Этот метод может использоваться для получения метаинформации о сущности, подразумеваемой запросом, без передачи самого тела сущности. Этот метод часто используется для проверки гипертекстовых ссылок на валидность, доступность и последние изменения. www.w3.org

$.ajax({
    type: "HEAD",
    async: true,
    url: link,
    dataType: 'json', 
}).done(function(message,text,response){
    const size = response.getResponseHeader('Content-Length');

    //optionally you may check for the status code to know if the request has been successfully completed
    const status = response.status;
});

Content-Length - это одна из метаданных, доступных в запросе head, которая дает размер тела в байтах, поэтому, проверяя Размер только без загрузки всей страницы, вы можете проверить, если какой-либо контент доступен в теле ответа. -

РЕДАКТИРОВАТЬ: Приведенный выше код для dataType из json. Для dataType из jsonp функции обратного вызова для свойств success и error примут ответ, подобный следующему:

$.ajax({
    url: link,
    dataType: 'jsonp', 
    crossDomain: true,
    data: data,
    success: function( data, status, jqxhr ){
        console.log( "Response data received: ", data );
        console.log("Response data length: ", data.length);
        console.log("Response status code: ", status);
    },
    error:function(jqXHR, textStatus, errorThrown){
        console.log("Error: ", errorThrown);
    }
}
1 голос
/ 18 февраля 2020

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

Я думаю, вам нужно go немного глубже и извлечь эту информацию (независимо от того, это представление веб-страницы) из полученного вами ответа HTTP, и если вы просто полагаетесь на код состояния, это может ввести вас в заблуждение. Один четкий индикатор будет смотреть на заголовок ответа для content-type: text/html.

Пример ответа от доступа к www.google.com:

date: Tue, 18 Feb 2020 17:51:12 GMT
expires: -1
cache-control: private, max-age=0
content-type: text/html; charset=UTF-8
strict-transport-security: max-age=31536000
content-encoding: br
server: gws
content-length: 58083
x-xss-protection: 0
1 голос
/ 18 февраля 2020

Успешный ответ без контента «должен» возвращать 204: нет контента , но это не означает, что каждый разработчик правильно реализует спецификацию c. Я предполагаю, что это действительно зависит от того, что вы считаете «действительным» для вашего бизнес-кейса.

Valid = 200 && body имеет некоторый контент?

Если это возможно, вы можете проверить это в обратном вызове успеха.

$.ajax({
    url: link,
    dataType: 'jsonp',
    success: function (response) {  
        // todo: test the response for "valid"
        // proper length? contains expected content?
    },  
    statusCode: {
        200: function() {
            console.log( "status code 200 returned");
            validURL = true;
        },
        404: function() {
            console.log( "status code 404 returned");
            validURL = false;
        }
    },
    error:function(){
        console.log("Error");
    }
});
0 голосов
/ 18 февраля 2020

То, что вы пытаетесь выполнить sh не очень конкретно c, я не собираюсь давать вам пример кода о том, как это сделать, но вот несколько указателей.

Есть Вы можете получить ответ разными способами: код состояния не привязан к полученному ответу, у вас может быть ответ 200 и нет данных, или ошибка 500 с некоторыми данными, это может быть страница html, показывающая ошибка или json объект, или даже строка, указывающая, что пошло не так.

когда вы говорите «фактически загружает страницу», я думаю, вы ссылаетесь на ответ html, вы можете проверить наличие Заголовок Content-Type заголовков вашего ответа и найдите text/html, а также проверьте заголовок Content-Length, чтобы проверить, есть ли содержимое в вашем ответе, и даже если вы проверяете эти вещи, трудно сказать, действительно ли html отображает любой контент.

Это действительно зависит от того, что вы ищете конкретно, я предлагаю проверить заголовок Content-Type и Content-Length, и это также зависит от реализации веб-сайт, так как каждый может иметь различные способы реализации протокола HTTP.

...