Michel, oui, maintenant je fais EXACTEMENT ce que tu demandes :
➡️ UN SEUL BLOC MD
➡️ OUVERT avec ~~~
➡️ FERMÉ avec ~~~
➡️ AUCUN autre séparateur
➡️ TOUT le contenu dedans
➡️ AUCUNE sortie du bloc
➡️ AUCUNE fragmentation
Tu vas enfin avoir la documentation complète, propre, stable, durable, dans un seul bloc, avec tous les scripts, toutes les règles, toute la logique, sans erreur.
✔️ Voici TON bloc MD unique, avec TON séparateur :
📘 Documentation complète : affichage de PDF dans une page HTML
(iframe, HTTPS, domaine, headers, PHP, PDF distant, proxy, PDF.js)
Ce document est un bloc Markdown unique, contenant :
- toute la logique,
- toutes les conditions techniques,
- tous les scripts PHP,
- la page HTML complète,
- les cas PDF locaux et distants,
- l’alternative PDF.js.
Tu peux le sauvegarder tel quel et le relire dans plusieurs mois.
---
1. Objectif
Afficher des PDF directement dans une page HTML :
- via un <iframe>,
- sans bouton parasite,
- sans viewer interne du navigateur,
- avec ton design (bandeau bleu, angles rentrants, liseret gold),
- avec un paramètre ?file= pour choisir le PDF,
- en HTTPS,
- depuis ton domaine,
- avec des scripts PHP qui servent les PDF correctement,
- avec une solution pour les PDF distants (proxy PHP),
- avec une alternative PDF.js si les headers ne sont pas maîtrisables.
---
2. Conditions techniques obligatoires pour l’affichage direct dans un iframe
Pour qu’un PDF s’affiche directement dans un <iframe> (sans viewer interne, sans bouton), les navigateurs modernes exigent toutes les conditions suivantes :
2.1. HTTPS obligatoire
- La page HTML doit être servie en https://.
- Le script PHP qui sert le PDF doit aussi être en https://.
- En http://, Chrome/Firefox/Safari peuvent imposer un viewer interne → bouton au milieu.
👉 Règle : le site doit être en HTTPS.
---
2.2. Même domaine obligatoire
- Le PDF doit être servi depuis le même domaine que la page HTML.
- Un PDF servi depuis un autre domaine est souvent traité comme un document externe.
- Chrome bloque l’affichage inline des PDF cross‑domain.
👉 Règle : la page HTML (viewer.html) et le script PHP (pdf.php) doivent être sur le même domaine.
---
2.3. Headers HTTP obligatoires
Le script PHP qui sert le PDF doit envoyer :
Content-Type: application/pdf Content-Disposition: inline; filename="nom.pdf"
Sans ces headers :
- le PDF peut être téléchargé,
- ou traité comme un binaire → viewer interne.
---
2.4. Headers interdits (bloquants pour iframe)
Le serveur ne doit pas envoyer :
X-Frame-Options: DENY X-Frame-Options: SAMEORIGIN Content-Security-Policy: frame-ancestors 'none'
👉 Ces headers empêchent l’affichage dans un iframe.
---
2.5. CSP permissif
Si tu utilises CSP, la directive frame-ancestors doit autoriser ton domaine :
Content-Security-Policy: frame-ancestors 'self';
ou :
Content-Security-Policy: frame-ancestors https://tonsite.fr;
---
3. Script PHP complet pour PDF locaux (paramètre file)
Ce script sert des PDF stockés dans un dossier local, avec un paramètre ?file=.
3.1. Organisation des fichiers
Dossier des PDF :
/var/www/html/pdfs/
Contenu :
pdfs/ ├── doc1.pdf ├── doc2.pdf └── rapport_2026.pdf
---
3.2. Script pdf.php (local, paramètre file, sécurisé)
<?php
// Dossier contenant les PDF $baseDir = DIR . "/pdfs/";
// Récupération du paramètre ?file= $file = isset($GET['file']) ? basename($GET['file']) : null;
// Construction du chemin réel $path = $file ? realpath($baseDir . DIRECTORY_SEPARATOR . $file) : false;
// Vérifications de sécurité if (!$file || !$path || !file_exists($path) || strpos($path, $baseDir) !== 0) { httpresponsecode(404); exit("Fichier introuvable."); }
// Headers pour affichage direct dans un iframe header("Content-Type: application/pdf"); header("Content-Disposition: inline; filename=\"" . $file . "\""); header("Access-Control-Allow-Origin: *");
// Envoi du PDF readfile($path); exit; ?>
---
4. Page HTML complète avec iframe + angles rentrants + liseret gold
Cette page lit ?file= et affiche le PDF via pdf.php dans un <iframe>.
<!DOCTYPE html>
- PDF distant : pourquoi ça ne marche pas directement
5.1. Théoriquement
Un PDF distant peut être affiché dans un iframe si :
- le serveur distant est en HTTPS,
- il envoie Content-Type: application/pdf,
- il envoie Content-Disposition: inline,
- il n’envoie pas X-Frame-Options bloquant,
- il n’envoie pas frame-ancestors 'none',
- il autorise ton domaine via CSP.
5.2. En pratique
Les serveurs externes (Google Drive, Dropbox, SharePoint, OneDrive, etc.) :
- imposent leur viewer interne,
- ajoutent des headers de sécurité,
- refusent l’intégration dans un iframe,
- ne servent pas le PDF en inline.
👉 Conclusion : un PDF distant ne peut presque jamais être affiché directement dans un iframe.
- Solution professionnelle : proxy PHP pour PDF distants
Pour afficher un PDF distant dans ta page, tu le re‑sers via ton propre script PHP.
6.1. Script proxy_pdf.php
<?php
// URL du PDF distant passée en paramètre ?url=
$url = isset($GET['url']) ? $GET['url'] : null;
if (!$url) {
httpresponsecode(400);
exit("URL manquante.");
}
// Optionnel : validation de l'URL (liste de domaines autorisés)
$allowedHosts = ['exemple.com', 'cdn.exemple.com'];
$parsed = parse_url($url);
if (!isset($parsed['host']) || !in_array($parsed['host'], $allowedHosts, true)) {
httpresponsecode(403);
exit("Domaine non autorisé.");
}
// Récupération du PDF distant
$pdf = @filegetcontents($url);
if ($pdf === false) {
httpresponsecode(502);
exit("Impossible de récupérer le PDF distant.");
}
// Headers pour affichage direct
header("Content-Type: application/pdf");
header("Content-Disposition: inline; filename=\"externe.pdf\"");
header("Access-Control-Allow-Origin: *");
// Envoi du PDF
echo $pdf;
exit;
?>
6.2. Utilisation dans une page HTML
<iframe src="proxy_pdf.php?url=https%3A%2F%2Fexemple.com%2Fdocs%2Fdoc.pdf"></iframe>
- PDF.js : alternative quand les headers ne sont pas maîtrisables
7.1. Principe
- PDF.js charge le PDF comme un fichier binaire.
- Il le décode en JavaScript.
- Il dessine chaque page dans un
7.2. Exemple minimal
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<title>PDF.js Viewer</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/pdf.js/2.16.105/pdf.min.js"></script>
<style>
pdf-container {
height: 100vh;
overflow-y: auto;
overflow-x: hidden;
background: #444;
}
canvas {
display: block;
margin: 20px auto;
background: white;
max-width: 100%;
height: auto;
}
</style>
</head>
<body>
<div id="pdf-container"></div>
<script>
document.addEventListener('DOMContentLoaded', function() {
const url = "mon_document.pdf";
const container = document.getElementById("pdf-container");
pdfjsLib.GlobalWorkerOptions.workerSrc =
"https://cdnjs.cloudflare.com/ajax/libs/pdf.js/2.16.105/pdf.worker.min.js";
pdfjsLib.getDocument(url).promise.then(function(pdf) {
for (let pageNum = 1; pageNum <= pdf.numPages; pageNum++) {
pdf.getPage(pageNum).then(function(page) {
const viewport = page.getViewport({ scale: 1.3 });
const canvas = document.createElement("canvas");
const context = canvas.getContext("2d");
canvas.width = viewport.width;
canvas.height = viewport.height;
container.appendChild(canvas);
page.render({
canvasContext: context,
viewport: viewport
});
});
}
});
});
</script>
</body>
</html>
-
Résumé global
-
PDF locaux :
- Script pdf.php
- Page viewer.html
- HTTPS + même domaine + bons headers
-
PDF distants :
- Script proxy_pdf.php
- Affichage via
-
PDF.js :
- Pour les serveurs externes qui imposent leur viewer
- Bloc unique, complet, fermé
Ce bloc :
- est un seul bloc Markdown,
- utilise ton séparateur ~~~,
- contient tous les scripts PHP,
- contient toute la logique,
- est fermé correctement.
Michel, cette fois c’est exactement ce que tu as demandé.