У меня есть страница VisualForce, содержащая изображение, которое я хочу отобразить в формате PDF. Эта визуализация выполняется как часть вызова контроллера, который берет обработанный большой двоичный объект PDF и прикрепляет его как файл к объекту. Если я просматриваю эти страницы в обычном Salesforce, он отлично работает, отображая PDF-файл, чтобы включить изображение. Если я делаю это как часть сообщества, изображение не отображается (хотя остальная часть PDF создается) и данные не запрашиваются (форма PDF пуста). Изображение размещено в Salesforce в виде вложенного файла и доступно во время рендеринга PDF.

Фрагмент контроллера:

// Get PDF...
PageReference pdf = Page.CustomReport;
pdf.getParameters().put('id', Id);
pdf.getParameters().put('imageUrl', prepareUrl(Id));
Blob body = pdf.getContent();
// Attach Blob to Object...

Фрагмент страницы ВФ:

<apex:image id="customImage" value="{!imageUrl}" alt="Custom Image" />

Я проверил, что URL-адрес действительно заполнен и действительно ссылается на рассматриваемое изображение, к которому я могу получить доступ с помощью запроса GET в своем браузере. Насколько я понимаю, механизм рендеринга PDF может работать в другом контексте, чем исходный контроллер, но я не могу объяснить, почему это работает в обычном Salesforce, но не в сообществе.

3
pmiller3 7 Июн 2019 в 23:52

1 ответ

Лучший ответ

Ну, я как бы ответил на свой вопрос, но не нашел никакой документации, подтверждающей это.

Рендеринг PDF действительно происходит как отдельный вызов с собственным контекстом. В обычном Salesforce это продолжает выполняться как пользователь, выполнивший первоначальный вызов контроллера. В сообществе это происходит не как аутентифицированный пользователь, а как неаутентифицированный Community Guest User. Рассматриваемый URL-адрес изображения защищен, и для доступа к нему требуется аутентифицированный пользователь. Базовые данные также защищены, поэтому PDF-файл не заполняется никакими значениями. Это подтверждается как журналами отладки, так и тем, что мне также удалось отобразить изображение с незащищенного URL-адреса (например, https://www.google.com/images/branding/googlelogo/1x/googlelogo_color_272x92dp.png).

Таким образом, кажется, варианты:

  • Следуйте другим, похожим ответам и размещайте эти изображения в статических ресурсах (что, для их подталкивания, потребует API метаданных и удержания ссылки на него). Также передайте остальные данные на страницу (вероятно, неприемлемо для конфиденциальных данных).
  • Подтолкните изображения к размещению в другом месте, где они будут незащищенными ресурсами, и снова держитесь за ссылку.
  • Передайте изображение в кодировке base64 на страницу, сделайте так, чтобы страница передала его незащищенному веб-сервису в обычном запросе GET, и получите изображение обратно. Подтверждено, что работает, как бы некрасиво это ни было.
  • Исправьте Salesforce или базовую библиотеку Flying Saucer, чтобы PDF-файлы могли отображать изображения в кодировке base64 и использовать кодировку base64 на странице VF, а не URL-адрес.
  • Полностью используйте другой механизм рендеринга PDF.
  • Получите доступ к странице VF с помощью HTTPRequest, а не PageReference.getContent(). Таким образом, вы можете манипулировать полями запроса, такими как заголовки, и можете установить аутентификацию в запросе. После этого страница VF будет работать как пользователь с предоставленной аутентификацией.

Мне бы хотелось увидеть некоторую документацию в Salesforce, в которой указывается разница в поведении между обычным использованием и сообществом, но пока мне не повезло.

1
pmiller3 7 Июн 2019 в 23:54
Я не хочу принимать свой собственный ответ, и ни один из вариантов не особенно привлекателен, но имитация нормального поведения кажется лучшей. Я, конечно, открыт для предложений по лучшему пути.
 – 
pmiller3
7 Июн 2019 в 23:19