Я собрал приведенный ниже код в чистом JavaScript, протестировал, и он работает.Весь исходный код (html, css и Javascript) + images и пример шрифта находятся здесь: на github .
Первый блок кода - это объект с методами для определенных расширений файлов: html
и css
.Второй поясняется ниже, но здесь есть краткое описание.
Это делает следующее:
- функция
check_file
принимает 2 аргумента: путь строки и функцию обратного вызова. - получает содержимое заданного пути
- получает расширение файла (
ext
) по указанному пути - вызывает метод объекта
srcFrom
[ext
], которыйвозвращает массив относительных путей, на которые ссылались в строковом контексте src
, href
и т. д. - выполняет синхронный вызов для каждого из этих путей в массиве путей
- haltsоб ошибке и возвращает сообщение об ошибке HTTP и путь, по которому возникла проблема, так что вы можете использовать его и для других проблем, таких как 403 (запрещено) и т. д.
Для удобства он разрешаетсяотносительные имена путей и не заботится о том, какой протокол используется (http или https, либо в порядке).Он также очищает DOM после анализа CSS.
var srcFrom = // object
{
html:function(str)
{
var prs = new DOMParser();
var obj = prs.parseFromString(str, 'text/html');
var rsl = [], nds;
['data', 'href', 'src'].forEach(function(atr)
{
nds = [].slice.call(obj.querySelectorAll('['+atr+']'));
nds.forEach(function(nde)
{ rsl[rsl.length] = nde.getAttribute(atr); });
});
return rsl;
},
css:function(str)
{
var css = document.createElement('style');
var rsl = [], nds, tmp;
css.id = 'cssTest';
css.innerHTML = str;
document.head.appendChild(css);
css = [].slice.call(document.styleSheets);
for (var idx in css)
{
if (css[idx].ownerNode.id == 'cssTest')
{
[].slice.call(css[idx].cssRules).forEach(function(ssn)
{
['src', 'backgroundImage'].forEach(function(pty)
{
if (ssn.style[pty].length > 0)
{
tmp = ssn.style[pty].slice(4, -1);
tmp = tmp.split(window.location.pathname).join('');
tmp = tmp.split(window.location.origin).join('');
tmp = ((tmp[0] == '/') ? tmp.substr(1) : tmp);
rsl[rsl.length] = tmp;
}
});
});
break;
}
}
css = document.getElementById('cssTest');
css.parentNode.removeChild(css);
return rsl;
}
};
А вот функция, которая получает содержимое файла и вызывает вышеуказанный объектный метод в соответствии с расширением файла:
function check_file(url, cbf)
{
var xhr = new XMLHttpRequest();
var uri = new XMLHttpRequest();
xhr.open('GET', url, true);
xhr.onload = function()
{
var ext = url.split('.').pop();
var lst = srcFrom[ext](this.response);
var rsl = [null, null], nds;
var Break = {};
try
{
lst.forEach(function(tgt)
{
uri.open('GET', tgt, false);
uri.send(null);
if (uri.statusText != 'OK')
{
rsl = [uri.statusText, tgt];
throw Break;
}
});
}
catch(e){}
cbf(rsl[0], rsl[1]);
};
xhr.send(null);
}
Чтобы использовать это, просто назовите это так:
var uri = 'htm/stuff.html'; // html example
check_file(uri, function(err, pth)
{
if (err)
{ document.write('Aw Snap! "'+pth+'" is missing !'); }
});
Пожалуйста, не стесняйтесь комментировать и редактировать, как вы хотите, я сделал это спешка, так что это может быть не так красиво:)