我知道这个问题可能已经被问过好几次了。 我想做的就是在移动屏幕网络浏览器中显示 PDF Blob。我尝试过使用嵌入标签和 iframe 标签,但它们都无法在移动屏幕网络浏览器中正常工作。仅供参考,嵌入和 iframe 标签在桌面屏幕中运行得很好。这是我的控制器
public function read_file($id) {
$findId = DB::connection('sqlsrv38')->table('kred_file_regulasi')->find($id);
if (!$findId) {
return response()->json([
'error' => 'File not found',
'data' => null,
], 404);
}
$filePath = $findId->nama_path;
if (!Storage::disk('ftp_edoc')->exists($filePath)) {
return response()->json([
'error' => 'File not found on storage',
'data' => $findId,
], 404);
}
try {
$fileContent = Storage::disk('ftp_edoc')->get($filePath);
return response($fileContent)
->header('Content-Type', 'application/pdf')
->header('Content-Disposition', 'inline; filename="' . $findId->nama_file . '"');
} catch (\Exception $e) {
return response()->json([
'error' => 'Error reading file: ' . $e->getMessage(),
'data' => $findId,
], 500);
}
}
这是我的刀片
@extends('layouts.media2');
@section('judule')
<li class="fas fa-solid fa-user-nurse text-success"></li> Daftar File Regulasi Keperawatan
@endsection
@section('isine')
<div class="container">
<div class="row">
<div class="col-4">
<div>
<h4>Jenis Regulasi</h4>
<div>
@foreach ($jenis_regulasi as $item)
<button class="btn btn-success w-100 mb-2 btn-jenis-reg" data-id="{{ $item->id }}">
<small class="font-weight-bold">{{ $item->jenis_reg }}</small>
</button>
@endforeach
</div>
</div>
</div>
<div class="col-8">
<h4>Nama Regulasi</h4>
<div class="h-100 d-flex flex-column" id="nama-file-container">
<h1 class="bg-info mb-2 w-100 h-75 display-4 p-2 rounded-lg text-center
" id="btn-nama-file">Pilih Jenis Regulasi</h1>
</div>
</div>
</div>
</div>
@endsection
@section('modal')
<div class="modal fade" id="modal-show-pdf" tabindex="-1" aria-labelledby="exampleModalLabel" aria-hidden="true">
<div class="modal-dialog modal-xl">
<div class="modal-content">
<div class="modal-header">
<div>
<p class="modal-title text-bold" id="modal-title"></p>
<small class="text-gray" id="modal-subtitle"></small>
</div>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<div id="kolom_saran" class="row d-flex flex-column mx-2"></div>
<embed id="pdf-frame" src="${url}" style="width: 100%; min-height: 450px;" frameborder="0" type="application/pdf"></embed>
</div>
</div>
</div>
</div>
@endsection
@push('js-script')
<script>
// Toast library
function infoToast(posisine,icone,infone) {
const Toast = Swal.mixin({
toast: true,
position: posisine,
showConfirmButton: false,
timer: 3000
});
Toast.fire({
icon: icone,
title: infone
});
}
function getFiles(dataId) {
$.ajax({
method: "POST",
url: "{{ route('keperawatan_fetch_files') }}",
data: {
_token: '{{ csrf_token() }}',
dataId: dataId,
},
success: function(response) {
var selectFileContainer = $('#nama-file-container');
selectFileContainer.empty();
response.forEach(function(file) {
selectFileContainer.append(
`<button class="btn btn-info mb-2 w-100 btn-show-pdf text-left" data-id="${file.id}" data-name="${file.nama_file}" data-wbm="${file.waktu_baca_min}">${file.nama_file}</button>`
);
});
},
error: function(xhr, status, error) {
console.error('AJAX Error:', status, error);
},
});
}
function startRead() {
var getTimeNow = new Date().toISOString();
return getTimeNow;
}
function convertMiliseconds(text) {
const split = text.split(" ");
const value = parseInt(split[0]);
const acuan = split[1];
let miliseconds = 0;
if(acuan.includes('menit')) {
miliseconds = value * 60 * 1000;
} else if (acuan.includes('jam')) {
miliseconds = value * 3600 * 1000;
}
return miliseconds;
}
$(document).ready(function() {
$('body').on('click', '.btn-jenis-reg', function (e) {
e.preventDefault();
var dataId = $(this).data('id');
getFiles(dataId);
});
$('body').on('click', '.btn-show-pdf', function () {
var mulai = startRead();
var fileId = $(this).data('id');
var fileName = $(this).data('name');
var waktuBacaMin = $(this).data('wbm');
var miliseconds = convertMiliseconds(waktuBacaMin);
var isMobile = window.innerWidth <= 768;
$.ajax({
url: `{{ route('keperawatan_read', ':id') }}`.replace(':id', fileId),
method: 'GET',
data: {
fileId: fileId,
_token: '{{ csrf_token() }}'
},
contentType: false,
cache: false,
processData: false,
xhrFields: {
responseType: 'blob'
},
success: function(response, status, xhr) {
var blob = new Blob([response], { type: 'application/pdf' });
var url = URL.createObjectURL(blob);
$('#kolom_saran').empty();
$('#modal-subtitle').text(`Tombol akan bisa diklik jika sudah memenuhi waktu minimal baca: ${waktuBacaMin}`)
let kolomSaran = `
<div class="d-flex flex-row align-items-center mb-2">
<input type="hidden" id="nama_file" value="${fileName}">
<input type="hidden" id="mulai" value="${mulai}">
<input type="hidden" id="nid_karyawan" value="{{ session('nidkaryawan') }}">
<input type="hidden" id="id_karyawan" value="{{ session('idkaryawane') }}">
<input type="hidden" id="id_unit_kerja" value="{{ session('unite_id') }}">
<textarea type="text" name="saran" id="saran" cols="80" rows="2" class="form-control form-control-sm" placeholder="Jika tidak ada saran dan masukkan, silahkan klik simpan untuk setor baca SPO"></textarea>
<button class="btn btn-success" id="btn-baca-spo" disabled>SIMPAN</button>
</div>`;
$('#kolom_saran').append(kolomSaran);
$('#modal-body').append(``)
setTimeout(() => {
$('#btn-baca-spo').removeAttr("disabled");
}, miliseconds);
$('#pdf-frame').attr('src', url);
$('#modal-title').text(fileName);
$('#modal-show-pdf').modal('show');
},
error: function(xhr) {
alert('Error: ' + xhr.status + ' - ' + xhr.statusText);
}
});
});
$('body').on('click', '#btn-baca-spo', function () {
var id_jenis_kegiatan = 4;
var topik = $('#nama_file').val();
var id_peran = 1;
var mulai = $('#mulai').val();
var akhir = new Date().toISOString();
var detail = $('#saran').val();
let nid_karyawan = $('#nid_karyawan').val();
let id_karyawan = $('#id_karyawan').val();
var periode = parseInt(new Date().getFullYear(), 10);
var id_unit_kerja = $('#id_unit_kerja').val();
console.log(typeof akhir, typeof mulai);
$.ajax({
url: `{{ route('keperawatan_add_aktf_kompetensi') }}`,
method: "POST",
data: {
id_jenis_kegiatan: id_jenis_kegiatan,
topik: topik,
id_peran: id_peran,
mulai: mulai,
akhir: akhir,
detail: detail,
nid_karyawan: nid_karyawan,
id_karyawan: id_karyawan,
periode: periode,
id_unit_kerja: id_unit_kerja,
_token: '{{ csrf_token() }}'
},
success: function(response) {
if (response.statuseKd === 200) {
console.log(response);
$('#modal-show-pdf').modal('hide');
infoToast('top', 'success', response.message);
}
},
error: function(xhr) {
if (xhr.status === 422) {
infoToast('toast-top-full-width', 'error', 'Terdapat kesalahan input, pastikan anda belum pernah melakukan setor aktifitas kompetensi ini');
}
}
})
});
});
</script>
@endpush
顺便说一句,我正在使用 Laravel 7 和 Bootstrap 4
在 PHP 中尝试一下:
public function read_file($id) {
$findId = DB::connection('sqlsrv38')->table('kred_file_regulasi')->find($id);
try {
//GET THE CONTENT OF THE FILE
$fileContent = Storage::disk('ftp_edoc')->get($filePath);
//RETURN THE CONTENT OF THE FILE AS BASE64 ENCODED
return response()->json([
'error' => false,
'b64_file' => base64_encode($fileContent)
]);
} catch (\Exception $e) {
return response()->json([
'error' => 'Error reading file: ' . $e->getMessage(),
'data' => $findId,
], 500);
}
}
这在你的 JavaScript 中:
从返回的数据生成一个base64数据url并将其设置为iframe的src。
$.ajax({
url: `{{ route('keperawatan_read', ':id') }}`.replace(':id', fileId),
method: 'GET',
dataType: 'json', // <----- EXPECT JSON SINCE ALL OF YOUR ERRORS RETURN JSON
data: {
fileId: fileId,
_token: '{{ csrf_token() }}'
},
success: function(data) {
//GENERATE A BASE64 DATA URL
var url = "data:application/pdf;base64,"+data.b64_file;
//SET THE URL AS THE SRC ATTRIBUTE OF THE IFRAME
$('#pdf-frame').attr('src', url);
},
error: function(xhr) {
alert('Error: ' + xhr.status + ' - ' + xhr.statusText);
}
});