Modern yöntem
File handling API'yi kullanma
Öncelikle, web uygulaması manifestinizde file_handlers
özelliğini tanımlayın. File processing API, action
özelliğini (işleme URL'si) ve accept
özelliğini belirtmenizi gerektirir. Bu, özellikle karşılık gelen dosya uzantılarının anahtarları ve dizileri olarak MIME türlerine sahip bir nesnedir.
{
"file_handlers": [
{
"action": "./",
"accept": {
"image/*": [".jpg", ".jpeg", ".png", ".webp", ".svg"]
}
}
]
}
Ardından, açık dosyaları launchQueue
üzerinden zorunlu olarak işlemek için File processing API'yi kullanmanız gerekir.
if ('launchQueue' in window && 'files' in LaunchParams.prototype) {
launchQueue.setConsumer((launchParams) => {
if (!launchParams.files.length) {
return;
}
for (const fileHandle of launchParams.files) {
// Handle the file.
}
});
}
Tarayıcı Desteği
- 102
- 102
- x
- x
Klasik yöntem
Klasik DataTransferItem.getAsFile()
yöntemini kullanarak
File PROCESS API desteklenmiyorsa dosyaları dosya gezgininden uygulamaya sürükleyip bırakabilirsiniz. DataTransferItem.getAsFile()
yöntemi, sürükleme veri öğesinin File
nesnesini döndürür.
Öğe bir dosya değilse bu yöntem null
değerini döndürür. Dosyayı okuyabiliyor olsanız da
ona yanıt yazamazsınız. Bu yöntemin dezavantajı, dizinleri desteklememesidir.
Progresif geliştirme
Aşağıdaki snippet, mümkün olduğunda File processing API'yi kullanır. Ayrıca, sürüklenen dosyaların işlenebilmesi için sürükle ve bırak işleyicileri kaydeder.
Web uygulaması manifestinde işlenebilecek dosya türlerini tanımlayın. File processing API'yi desteklemeyen tarayıcılar bunu yoksayar.
{
"file_handlers": [
{
"action": "./",
"accept": {
"image/*": [".jpg", ".jpeg", ".png", ".webp", ".svg"]
}
}
]
}
// File Handling API
const handleLaunchFiles = () => {
window.launchQueue.setConsumer((launchParams) => {
if (!launchParams.files.length) {
return;
}
launchParams.files.forEach(async (handle) => {
const file = await handle.getFile();
console.log(`File: ${file.name}`);
// Do something with the file.
});
});
};
if ('launchQueue' in window && 'files' in LaunchParams.prototype) {
handleLaunchFiles();
}
// This is the drag and drop zone.
const elem = document.querySelector('main');
// Prevent navigation.
elem.addEventListener('dragover', (e) => {
e.preventDefault();
});
// Visually highlight the drop zone.
elem.addEventListener('dragenter', (e) => {
elem.style.outline = 'solid red 1px';
});
// Visually unhighlight the drop zone.
elem.addEventListener('dragleave', (e) => {
elem.style.outline = '';
});
// This is where the drop is handled.
elem.addEventListener('drop', async (e) => {
// Prevent navigation.
e.preventDefault();
// Unhighlight the drop zone.
elem.style.outline = '';
// Prepare an array of promises…
const fileHandlesPromises = [...e.dataTransfer.items]
// …by including only files (where file misleadingly means actual file _or_
// directory)…
.filter((item) => item.kind === 'file')
// …and, depending on previous feature detection…
.map((item) => item.getAsFile());
// Loop over the array of promises.
for await (const handle of fileHandlesPromises) {
// This is where we can actually exclusively act on the files.
if (handle.isFile) {
console.log(`File: ${handle.name}`);
// Do something with the file.
}
}
});
Daha fazla bilgi
- Yüklü web uygulamalarının dosya işleyiciler olmasına izin verme
- File System Access API: yerel dosyalara erişimi basitleştirme
Demo
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link rel="manifest" href="manifest.json" />
<title>How to handle files opened from the file explorer</title>
<link rel="stylesheet" href="style.css" />
<!-- TODO: Devsite - Removed inline handlers -->
<!-- <script>
if ('serviceWorker' in navigator) {
window.addEventListener('load', async () => {
const registration = await navigator.serviceWorker.register(
'sw.js',
);
console.log(
'Service worker registered for scope',
registration.scope,
);
});
}
</script>
<script src="script.js" type="module"></script> -->
</head>
<body>
<h1>How to handle files opened from the file explorer</h1>
<p>Install the app. After the installation, try opening an image file from the file explorer with the app.
</body>
</html>
html {
box-sizing: border-box;
font-family: system-ui, sans-serif;
color-scheme: dark light;
}
*, *:before, *:after {
box-sizing: inherit;
}
body {
margin: 1rem;
}
img {
height: auto;
max-width: 100%;
display: block;
}
if ('launchQueue' in window && 'files' in LaunchParams.prototype) {
launchQueue.setConsumer((launchParams) => {
if (!launchParams.files.length) {
return;
}
for (const fileHandle of launchParams.files) {
document.body.innerHTML += `${fileHandle.name}
`;
}
});
}