Базопасный placeholder-болванка javascript ответа

На сервере динамически генерируется javascript ответ (допустим script.js). При этом какая-то часть файла — статическая и одинаковая для всех клиентов, а какая-то должна быть заменена для каждого клиента отдельно. При этом заменой занимается некий серверный язык. Задача: предоставить файл-шаблон, в определенное место в котором будут подставляться данные. Первое, что приходит на ум выглядит как-то так:

(function () {
	var data = #DATA_PLACEHOLDER#;
	var errors = #ERRORS_PLACEHOLDER#;
	var all = {};
		
	all.data = data;
	all.errors = errors;
	window.provide = processData(all);
}());

Файл получается невалидным, что влечет ряд последствий:

  • Его валидацию надо исключить из общей валидации проекта, или реализовывать отдельную.
  • При исключении файла из валидации велик шанс синтаксической ошибки при последующей его правке (сборка проекта пройдет успешно, но клиентская часть не отработает)
  • В случае отказа бекэнда инициализация не произойдет, и код, зависящий от кода в файле, что мы генерируем, завалится, обращаясь к необъявленной переменной (provide).

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

(function () {
	var data = (function () {return /*!DATA_PLACEHOLDER*/})() || {};
	var errors = (function () {return /*!ERRORS_PLACEHOLDER*/})() || [];
	var all = {};
	
	all.data = data;
	all.errors = errors;
	window.provide = processData(all);
}());

Уже намного лучше. Файл валиден, теперь его можно не исключать из процесса проверки всего проекта. А так-же в случае с проблемами на бекэнде, клиентская часть продолжает инициализироваться. Тут она сможет сама решить, как поступать в случае падения серверов.

Однако не все так безрадостно.

var data = (function() {return
	{
		importantValue: true
	}
})() || {};
console.log(data.importantValue); // undefined

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

И вот оно, финальное решение: передадим данные аргументом, и вернем их-же.

(function () {
	var data = (function (data) {return data})(/*!DATA_PLACEHOLDER*/) || {};
	var errors = (function (errors) {return errors})(/*!ERRORS_PLACEHOLDER*/) || [];
	var all = {};
		
	all.data = data;
	all.errors = errors;
	window.provide = processData(all);
}());

На выходе — пуленепробиваемая, валидная конструкция для последующего наполнения данными.

Share
Send
Popular