Вам будет трудно это сделать, потому что при создании экземпляра URL
:
u = new URL('http://example.com/');
и Object.keys(u)
, и Object.getOwnPropertyNames(u)
вернут пустой массив, и даже JSON.stringify(u)
не будетздесь вам поможет, поскольку в результате получается одна строка верхнего уровня, а не JSON-представление объекта.
Таким образом, вы не сможете легко проверить наличие каких-либо дополнительных полей, если только вы вручную не проанализируете выводutil.format(u)
или что-то в этом роде - но вам все равно нужно проверить ключи объекта (включая не перечисляемые свойства), чтобы проверить другие объекты, которые не являются экземплярами URL
.
Таким образом, наиболее разумное решениебыло бы проверить, если u instanceof URL
и если это правда, то поверьте, что это хорошо, но если это ложь, то проверьте конкретные свойства.
Но имейте в виду, что url.format()
не нуждается в фактическомURL
экземпляр, например, эти две строки имеют одинаковый эффект:
a = url.format(new URL('http://example.com/'));
b = url.format({ protocol: 'http', host: 'example.com', pathname: '/' });
// a === b
Чтобы проверить, если экземпляр URL
(или любой другой объект) имеет следующие свойства и ониСтроки, как это должно быть в экземпляре URL
, вы можете использовать что-то вроде:
const k = [
'href',
'origin',
'protocol',
'username',
'password',
'host',
'hostname',
'port',
'pathname',
'search',
'hash',
];
const validUrl = u => k.filter(k => typeof u[k] === 'string').length === k.length;
Это вернет true
для обычных URL
экземпляров:
u = new URL('http://example.com/');
console.log(validUrl(u));
но и для других объектов, если у них есть все обязательные поля.Но имейте в виду, что для url.format()
не требуются все поля, как вы можете видеть в приведенном выше примере, так что таким образом вы бы отклонили некоторые значения, которые были бы идеально подходящими для url.format()
, например:
u = { protocol: 'http', host: 'example.com', pathname: '/' };
Подводя итог:
Реальные URL
экземпляры не показывают, какие свойства у них есть, поэтому вы не сможете легко проверить дополнительные свойства, но я бы не советовал делатьчто в любом случае, потому что ваш код сломается, если URL
когда-либо будет расширен с новыми свойствами, которые могут произойти в будущем.
Чтобы увидеть, есть ли у него все необходимое (по вашему мнению - не обязательно по мнениюurl.format()
!) Свойств, вы можете написать простую функцию валидатора, но тогда вы не сможете пропустить пустые свойства, такие как username
, если их нет, и вам придется явно передавать пустые строки для всех пустых свойств, если вы хотитечтобы иметь возможность использовать URL
-подобные объекты, которые в противном случае совместимы с url.format()
.
Может быть, вы хотите проверить только некоторые поля, такие как protocol, host и pathname, но тогда вы должны обработать, что url.format()
займет либо host
, либо hostname
, предпочитая host
, если оба доступны и т. д.
Вы также можете попробовать взломать как этот:
const testUrl = u => {
try {
new URL(url.format(u));
} catch (e) {
throw new TypeError('your error message');
}
};
и есть функция, которая экспериментально проверяет, работает ли заданное значение с url.format()
, давая URL-адрес, доступный для new URL()
, например:
testUrl(new URL('http://example.com')); // ok
testUrl({host: 'example.com', protocol: 'http'}); // ok
testUrl({host: 'example.com'}); // throws a TypeError
Теперь в вашей функциикоторый вызывает url.format(urlObject)
, все, что вам нужно сделать, это добавить: testUrl(urlObject)
в строке раньше, и он выдаст исключения, которые вы описываете.
В общем, это сложный вопрос.Вы можете сделать это разными способами, но у всех есть некоторые недостатки.URL
экземпляры на самом деле довольно странные, и даже Джой ломается над ними!
Например:
!joi.object({ host: joi.string().required() }).validate({ host: 'example.com' }).error;
// returns true
!joi.object({ host: joi.string().required() }).validate({ nohost: 'example.com' }).error
// returns false
!joi.object({ host: joi.string().required() }).validate(new URL('http://example.com/')).error;
// this throws an exception!
// TypeError: Cannot read property 'host' of undefined
// WTF???
Если даже Джой не может проверить URL
экземпляры, то их нелегко проверить.
Надеемся, что некоторые из приведенных выше примеров сделают то, что вам нужно.