Pertanyaan Unduh di browser dengan permintaan ajax


Saya bekerja dengan AngularJS dan saya mencoba menghasilkan PDF dalam php. Inilah yang saya miliki di saya controller.js:

$scope.downloadPDF = function(){
    $http.post('/download-pdf', { fid: $routeParams.fid })
        .success(function(data, status, headers, config){
            console.log("success");
        })
        .error(function(data, status, headers, config){
            console.log("error");
        });
};

Dalam file php saya, saya memiliki hal berikut untuk membuat PDF dengan Perpustakaan FPDF:

function download_pdf()
{
    $id = $_POST['fid'];

    $pdf = new FPDF();

    $pdf->AddPage();
    $pdf->SetFont('Arial','B',16);
    $pdf->Cell(40,10,'Hello World!');

    header('Content-Type: application/pdf');
    header('Content-Disposition: attachment; filename=' . $id . '.pdf');

    $pdf->Output('Order123.pdf', 'D');
}

Tetapi permintaan tersebut menanggapi ini daripada membuka dialog simpan untuk menyimpan pdf saya.

% PDF-1.3       3 0 obj       <>       endobj       4 0 obj       <>       aliran       x3Rðâ2Ð35W (çr       QÐw3T04Ó30PISp           êZ * [¤ (hx¤æää + çå¤ (j * dÔ7W       endstream       endobj       1 0 obj       <       endobj       5 0 obj       <       endobj       2 0 obj       <<       / ProcSet [/ PDF / Teks / ImageB / ImageC / ImageI]       / Font <<       / F1 5 0 R   >       / XObject <<   >   >       endobj       6 0 obj       <<       / Produser (FPDF 1.7)       / CreationDate (D: 20150611094522)   >       endobj       7 0 obj       <<       / Ketik / Katalog       / Halaman 1 0 R   >       endobj       xref       0 8       0000000000 65535 f       0000000228 00000 n       0000000416 00000 n       0000000009 00000 n       0000000087 00000 n       0000000315 00000 n       0000000520 00000 n       0000000595 00000 n       trailer       <<       / Ukuran 8       / Root 7 0 R       / Info 6 0 R   >       startxref       644       %% EOF

Saya telah menggunakan PHPExcel perpustakaan dan ini bekerja:

$objWriter = PHPExcel_IOFactory::createWriter($ea, 'Excel2007');

// We'll be outputting an excel file
header('Content-type: application/vnd.ms-excel');

// It will be called Submission on [date_now].xls
header('Content-Disposition: attachment; filename="' . $filename . '.xls' . '"');

// Write file to the browser
$objWriter->save('php://output');

Sekarang bagaimana saya bisa membuat ini bekerja untuk PDF saya?

MEMPERBARUI:

Saya telah mengedit kode saya ke ini:

$pdf = new FPDF();

$pdf->AddPage();
$pdf->SetFont('Arial','B',16);
$pdf->Cell(40,10,'Hello World!');

$filename = DXS_VKGROUP_PLUGIN_LIB_DIR . 'uploads/' . $_POST['fid'] . '.pdf';

$pdf->Output($filename, 'F'); // Save file locally

header('Pragma: public');
header('Expires: 0');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Content-Type: application-download');
header('Content-Length: ' . filesize($filename));
header('Content-Transfer-Encoding: binary');
header('Content-Disposition: attachment; filename="' . $filename . '"');

$handle = fopen($filename, 'rb');
fpassthru($handle);
fclose($handle);

File disimpan secara lokal tetapi unduhan tidak berfungsi. Itu tidak mendapatkan dialog saya untuk menyimpan pdf. Apa yang saya lakukan salah?

PERBARUI 2

Saya sekarang mencoba untuk berubah application-download di application/pdf. Dia menyimpan file secara lokal tetapi saya tidak mendapatkan kotak dialog unduhan.

Tanggapannya terlihat seperti ini (ketika saya memeriksanya Jaringan di Chrome):

% PDF-1.3       3 0 obj       <>       endobj       4 0 obj       <>       aliran       x3Rðâ2Ð35W (çr       QÐw3T04Ó30PISp           êZ * [¤ (hx¤æää + çå¤ (j * dÔ7W       endstream       endobj       1 0 obj       <       endobj       5 0 obj       <       endobj       2 0 obj       <<       / ProcSet [/ PDF / Teks / ImageB / ImageC / ImageI]       / Font <<       / F1 5 0 R   >       / XObject <<   >   >       endobj       6 0 obj       <<       / Produser (FPDF 1.7)       / CreationDate (D: 20150617090832)   >       endobj       7 0 obj       <<       / Ketik / Katalog       / Halaman 1 0 R   >       endobj       xref       0 8       0000000000 65535 f       0000000228 00000 n       0000000416 00000 n       0000000009 00000 n       0000000087 00000 n       0000000315 00000 n       0000000520 00000 n       0000000595 00000 n       trailer       <<       / Ukuran 8       / Root 7 0 R       / Info 6 0 R   >       startxref       644       %% EOF


32
2018-06-11 09:48


asal


Jawaban:


MEMPERBARUI 

Metode menggunakan FileSaver.js juga tidak berfungsi, sepertinya tidak ada cara untuk secara paksa memanggil Save As Dialog asli melalui JavaScript saja, kecuali hanya sebagai save execCommand untuk IE. Memeriksa Apakah execCommand SaveAs berfungsi di Firefox?

Termasuk FileSaver.js sebagai ketergantungan dalam proyek Anda

Mengubah downloadPDF berfungsi sebagai berikut

 $scope.downloadPDF = function() {
    $http.post('/download-pdf', {
        fid: $routeParams.fid
      }, {
        responseType: 'arraybuffer'
      })
      .success(function(data, status, headers, config) {
        // Convert response data to Blob
        var file = new Blob([data], {
          type: 'application/pdf'
        });
        // Call the File Saver method to save the above Blob,this will show Save As dialog
        saveAs(file, "test.pdf");
      })
      .error(function(data, status, headers, config) {
        console.log("error");
      });

 };

Itu Blob objek akan bekerja di sebagian besar browser modern tetapi ada dukungan terbatas untuk IE <10, periksa https://github.com/eligrey/FileSaver.js#supported-browsers untuk polyfill

Hapus juga Content-Disposition: attachment dan Content-Type: application-download header karena kami tidak ingin browser menangani proses pengunduhan

Ini demo kerja http://plnkr.co/edit/9r1tehQ94t5vkqZfZuQC?p=preview , ini menunjukkan permintaan GET ke PDF


5
2018-06-23 04:05



Biarkan saya menyarankan Anda satu hal.

Hanya dengan AJAX Anda tidak dapat mengunduh file apa pun. Anda perlu membuat file .zip terlebih dahulu dengan panggilan ajax dan setelah itu mendapatkan jalur file tersebut Anda harus membuka file tersebut menggunakan perintah apa pun.

Berikut satu contoh yang cocok untuk saya: :)

$http.post('www.abc.com/zipcreate', {'id': id}).then(function (zipurl) {
                    $window.location = zipurl;
            });

Tentunya, itu berhasil. Coba sekali. :)

EDIT:

Atau Anda bisa menggunakannya

$window.location = 'abc.com/link';

di 'abc.com/link':  gunakan kode di bawah ini:

  header("Content-type: application/octet-stream");
  header("Content-Disposition: attachment; filename=".$name);
  header("Pragma: no-cache");
  header("Expires: 0");
  readfile($file);
  exit;

Anda akan mendapatkan file Anda di daftar unduhan.


3
2018-06-24 06:56



Menurut dokumentasi Anda dapat mengatur parameter ke-2 ke D:

$pdf->Output('Order123.pdf', 'D');

Jika Anda ingin menangani semua detail sendiri menggunakan file yang disimpan, ini adalah bagaimana saya menyajikan PDF ke peramban untuk mengunduh dari PHP:

header('Pragma: public');
header('Expires: 0');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Content-Type: application-download');
header('Content-Length: ' . filesize('file.pdf'));
header('Content-Transfer-Encoding: binary');
header('Content-Disposition: attachment; filename="file.pdf"');
$handle = fopen('file.pdf', 'rb');
fpassthru($handle);
fclose($handle);

Memperbarui:

Harap verifikasi bahwa file PDF sebenarnya sedang dibuat. Apakah proses server web memiliki akses tulis ke jalur itu? Apakah FPDF dimasukkan dengan benar? Saya membuat ini pada tes VM dan itu disajikan file 1.pdf untuk unduhan, yang dibuka dan berisi "Hello World!":

<?php

require('/var/www/html/fpdf17/fpdf.php');

$_POST = array('fid' => '1');

$pdf = new FPDF();

$pdf->AddPage();
$pdf->SetFont('Arial', 'B', 16);
$pdf->Cell(40, 10, 'Hello World!');

$filename = '/tmp/' . $_POST['fid'] . '.pdf';

$pdf->Output($filename, 'F'); // Save file locally

header('Pragma: public');
header('Expires: 0');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Content-Type: application-download');
header('Content-Length: ' . filesize($filename));
header('Content-Transfer-Encoding: binary');
header('Content-Disposition: attachment; filename="' . basename($filename) . '"');

$handle = fopen($filename, 'rb');
fpassthru($handle);
fclose($handle);

unlink($filename);

?>

2
2018-06-11 12:17



Dengan ajax itu tidak mungkin.
Sebaliknya apa yang dapat Anda lakukan adalah, tekan tindakan Anda melalui pengiriman formulir javascript.

misalnya., document.getElementById(formID).action= actionName.

document.getElementById(formID).submit();  

Di sini formID adalah id form Anda dan actionName akan '/download-pdf' seperti yang telah Anda tetapkan.

Di kelas aksi Anda - atur header tanggapan

getResponse().setContentType("application/pdf");
getResponse().setHeader("Content-Disposition",  " attachment; filename= "+"pdffile.pdf");

Ini akan menyebabkan file Anda diunduh dengan namafile = pdffile.pdf.


2
2018-06-23 04:47



header('Content-Type: application/octet-stream');
header("Content-Transfer-Encoding: Binary");
header("Content-disposition: attachment; filename=\"" . basename($file_url) . "\"");

Atau menggunakan BLOB:

 $scope.downloadPDF = function() {
    $http.post('/download-pdf', {
        fid: $routeParams.fid
      }, {
        responseType: 'arraybuffer'
      })
      .success(function(data, status, headers, config) {

        var file = new Blob([data], {
          type: 'application/pdf'
        });
        var url = URL.createObjectURL(blob);
        window.location.href = url;
      })
      .error(function(data, status, headers, config) {
        console.log("error");
      });

 };

Atau buat elemen dengan download atribut:

$scope.downloadPDF = function() {
    $http.get('http://46.101.139.188/demo.pdf', {
      }, {
        responseType: 'arraybuffer'
      })
      .success(function(data, status, headers, config) {

        var file = new Blob([data], {
          type: 'application/pdf'
        });
        var url = URL.createObjectURL(file);
        var a = document.createElement('a');
        a.setAttribute('download', 'download');
        a.setAttribute('href', url);

         var event = new MouseEvent('click', {
          'view': window,
          'bubbles': true,
          'cancelable': true
        });
        a.dispatchEvent(event);
      })
      .error(function(data, status, headers, config) {
        console.log("error");
      });
 };

demo plnkr


2
2018-06-23 05:48



Ini tidak mungkin dengan (hanya) AJAX.

Ada dua teknik utama yang bisa Anda gunakan di sini, keduanya tanpa menggunakan JavaScript untuk melakukan unduhan yang sebenarnya. Gagasan umumnya adalah Anda mengarahkan browser ke sumber daya yang akan menyediakan dokumen yang diinginkan; jika Anda mengarahkan ke unduhan itu tidak akan meninggalkan halaman tetapi menunjukkan dialog Simpan sebagai gantinya. Topik serupa dibahas dalam pertanyaan ini.

DAPATKAN Permintaan

location.href = '/download-pdf?fid=' + encodeURIComponent($routeParams.fid);

Sesuaikan skrip sisi server Anda untuk digunakan $_GET['fid'].

Permintaan POST

Server membuat sumber daya dan merespons dengan URL tempat sumber daya dapat ditemukan:

$http.post('/download-pdf', { fid: $routeParams.fid })
    .success(function(data, status, headers, config) {
        // follow location provided by server
        location.href = data.redirect_url;
        console.log("success");
    })
    .error(function(data, status, headers, config){
        console.log("error");
    });

Sesuaikan skrip sisi server Anda untuk mengembalikan respons JSON yang sesuai setelah membuat sumber daya baru.


1
2018-06-23 05:09



Kirim dokumen ke tujuan yang ditentukan: browser, file atau string. Dalam hal browser, plug-in dapat digunakan (jika ada) atau unduhan (kotak dialog "Save as") mungkin dipaksa.

Metode pertama panggilan Tutup () jika diperlukan untuk mengakhiri dokumen.

Parameter

nama: 

Nama file. Jika tidak ditentukan, dokumen akan dikirim ke browser (tujuan I) dengan nama doc.pdf.

dest

Tujuan tempat mengirim dokumen. Ini dapat mengambil salah satu dari nilai berikut:

  • SAYA: kirim file inline ke browser. Plug-in digunakan jika tersedia. Nama yang diberikan oleh nama digunakan ketika seseorang memilih "Simpan sebagai "opsi pada tautan yang menghasilkan PDF.
  • D: kirim ke browser dan paksa unduhan file dengan nama yang diberikan dengan nama.
  • F: simpan ke file lokal dengan nama yang diberikan oleh nama (mungkin termasuk jalur).
  • S: kembalikan dokumen sebagai string. nama diabaikan.

-1
2018-06-23 13:20