Я знаю, что существует много вопросов, уже существующих на SO, связанных с этой проблемой, например:
- Создайте файл в памяти для загрузки пользователем, а не через сервер
- Использование HTML5/Javascript для создания и сохранения файла
- Ограничения на размер URL-адреса протокола передачи данных
- Сохранить файл Javascript с именем файла
- Создание Blob из строки base64 в JavaScript
- Не удалось выполнить 'atob' в 'Window'
Этот вопрос очень специфичен для Safari на iOS 8.1.3 (Mobile, iPad 2+). У нас есть автономное веб-приложение AngularJS, использующее Application Cache и IndexedDB для хранения данных. Один вид данных - это документы PDF, которые могут быть относительно большими: максимум 25 мегабайт. Мы сохраняем эти файлы в IndexedDB, и когда пользователь хочет его загрузить, у нас есть этот файл в памяти в браузере с JavaScript.
Проблема в том, когда пользователь хочет ее сохранить. Ошибка Safari Mobile может быть связана с ограничением размера URI данных или чем-то еще.
this.save = function (file) {
    var mediaType = "application/pdf";
    var link = document.createElement("a");
    var blob = new Blob([this.fromBase64ToBinary(file.content)], { type: mediaType });
    var blobUrl = URL.createObjectURL(blob);
    document.body.appendChild(link);
    link.download = file.name;
    link.href = blobUrl;
    link.click();
    document.body.removeChild(link);
};
В службе у нас есть функция save(file), где file - объект, содержащий два свойства:
-  name: имя файла;
-  content: данные файла, который кодируется базой 64, затем преобразуем его в двоичный.
Функция atob() может быть причиной? Когда я делаю пошаговую отладку на iPad, запускающем этот код, он падает прямо там (то есть: строка с var byteCharacters = atob(b64Data);).
this.fromBase64ToBinary = function (base64) {
    var byteCharacters = atob(base64);
    var byteNumbers = new Array(byteCharacters.length);
    for (var i = 0; i < byteCharacters.length; i++) {
        byteNumbers[i] = byteCharacters.charCodeAt(i);
    }
    return new Uint8Array(byteNumbers);
};
