Closed Febtw closed 1 year ago
I agree that it would be a nice feature. It's not always possible to request the file by url, though, as it would be cross origin and could be blocked. An alternative is that it could be a browser extension.
I agree that it would be a nice feature. It's not always possible to request the file by url, though, as it would be cross origin and could be blocked. An alternative is that it could be a browser extension.
Thank you for your approval! Browser extension is very easy and convenient to use, but what I think is that through the api, users can not only read online e-books, but also embed and display ebooks on their own websites, making it more convenient to use across devices. Browser extension may not be very friendly to mobile devices, because most mobile browsers cannot install extensions.
Well, here's a really quick patch. It requires relaxing connect-src
to accept *
. I think this is fine, because unsafe-inline
is still blocked, and script-src
only accepts 'self'
, not blob:
. Also, it requires downloading the whole file. No range requests. Also it doesn't have a proper loading screen.
diff --git a/reader.html b/reader.html
index ec375bb..38bdd7b 100644
--- a/reader.html
+++ b/reader.html
@@ -2,7 +2,7 @@
<meta charset="utf-8">
<meta name="color-scheme" content="light dark">
<meta name="viewport" content="width=device-width, initial-scale=1">
-<meta http-equiv="Content-Security-Policy" content="default-src 'self' blob:; script-src 'self'; style-src 'self' blob: 'unsafe-inline'; img-src 'self' blob: data:; connect-src 'self' blob: data:; frame-src blob: data:; object-src blob: data:; form-action 'none';">
+<meta http-equiv="Content-Security-Policy" content="default-src 'self' blob:; script-src 'self'; style-src 'self' blob: 'unsafe-inline'; img-src 'self' blob: data:; connect-src 'self' blob: data: *; frame-src blob: data:; object-src blob: data:; form-action 'none';">
<title>E-Book Reader</title>
<style>
:root {
diff --git a/reader.js b/reader.js
index 304a049..7e12197 100644
--- a/reader.js
+++ b/reader.js
@@ -48,14 +48,14 @@ const makeDirectoryLoader = async entry => {
}
const isCBZ = ({ name, type }) =>
- type === 'application/vnd.comicbook+zip' || name.endsWith('.cbz')
+ type === 'application/vnd.comicbook+zip' || name?.endsWith('.cbz')
const isFB2 = ({ name, type }) =>
- type === 'application/x-fictionbook+xml' || name.endsWith('.fb2')
+ type === 'application/x-fictionbook+xml' || name?.endsWith('.fb2')
const isFBZ = ({ name, type }) =>
type === 'application/x-zip-compressed-fb2'
- || name.endsWith('.fb2.zip') || name.endsWith('.fbz')
+ || name?.endsWith('.fb2.zip') || name?.endsWith('.fbz')
const getView = async (file, emit) => {
let book
@@ -320,3 +320,10 @@ dropTarget.addEventListener('dragover', dragOverHandler)
$('#file-input').addEventListener('change', e =>
open(e.target.files[0]).catch(e => console.error(e)))
$('#file-button').addEventListener('click', () => $('#file-input').click())
+
+const params = new URLSearchParams(location.search)
+const url = params.get('url')
+if (url) fetch(url)
+ .then(res => res.blob())
+ .then(blob => open(blob))
+ .catch(e => console.error(e))
You can test this this locally with python -m http.server
and http://0.0.0.0:8000/reader.html?url=https://s3.amazonaws.com/moby-dick/moby-dick.epub. Note that the file is from Epub.js examples.
Well, here's a really quick patch. It requires relaxing
connect-src
to accept*
. I think this is fine, becauseunsafe-inline
is still blocked, andscript-src
only accepts'self'
, notblob:
. Also, it requires downloading the whole file. No range requests. Also it doesn't have a proper loading screen.diff --git a/reader.html b/reader.html index ec375bb..38bdd7b 100644 --- a/reader.html +++ b/reader.html @@ -2,7 +2,7 @@ <meta charset="utf-8"> <meta name="color-scheme" content="light dark"> <meta name="viewport" content="width=device-width, initial-scale=1"> -<meta http-equiv="Content-Security-Policy" content="default-src 'self' blob:; script-src 'self'; style-src 'self' blob: 'unsafe-inline'; img-src 'self' blob: data:; connect-src 'self' blob: data:; frame-src blob: data:; object-src blob: data:; form-action 'none';"> +<meta http-equiv="Content-Security-Policy" content="default-src 'self' blob:; script-src 'self'; style-src 'self' blob: 'unsafe-inline'; img-src 'self' blob: data:; connect-src 'self' blob: data: *; frame-src blob: data:; object-src blob: data:; form-action 'none';"> <title>E-Book Reader</title> <style> :root { diff --git a/reader.js b/reader.js index 304a049..7e12197 100644 --- a/reader.js +++ b/reader.js @@ -48,14 +48,14 @@ const makeDirectoryLoader = async entry => { } const isCBZ = ({ name, type }) => - type === 'application/vnd.comicbook+zip' || name.endsWith('.cbz') + type === 'application/vnd.comicbook+zip' || name?.endsWith('.cbz') const isFB2 = ({ name, type }) => - type === 'application/x-fictionbook+xml' || name.endsWith('.fb2') + type === 'application/x-fictionbook+xml' || name?.endsWith('.fb2') const isFBZ = ({ name, type }) => type === 'application/x-zip-compressed-fb2' - || name.endsWith('.fb2.zip') || name.endsWith('.fbz') + || name?.endsWith('.fb2.zip') || name?.endsWith('.fbz') const getView = async (file, emit) => { let book @@ -320,3 +320,10 @@ dropTarget.addEventListener('dragover', dragOverHandler) $('#file-input').addEventListener('change', e => open(e.target.files[0]).catch(e => console.error(e))) $('#file-button').addEventListener('click', () => $('#file-input').click()) + +const params = new URLSearchParams(location.search) +const url = params.get('url') +if (url) fetch(url) + .then(res => res.blob()) + .then(blob => open(blob)) + .catch(e => console.error(e))
You can test this this locally with
python -m http.server
and http://0.0.0.0:8000/reader.html?url=https://s3.amazonaws.com/moby-dick/moby-dick.epub. Note that the file is from Epub.js examples.
I tried the code and it has worked almost perfectly.
epub/azw/azw3/mobi files could be read from local and online.
fb2/fb2.zip/cbz files, I don't use often, work normally from local, fail online.
error code on Edge browser
And it works well with Alist (A file list program that supports multiple storage)
tested files:
epub file from https://s3.amazonaws.com/moby-dick/moby-dick.epub
azw file from Kindle E-Reader User and Quick Start Guides, from https://kindle.s3.amazonaws.com/EN_US_Kindle_Users_Guide.azw To allow cross origin, it could be download from my site https://crossfireqq.cf/EN_US_Kindle_Users_Guide.azw
azw3 file from https://filesamples.com/formats/azw3, from https://filesamples.com/samples/ebook/azw3/Alices%20Adventures%20in%20Wonderland.azw3 To allow cross origin check, it could be download from my site https://crossfireqq.cf/Alices%20Adventures%20in%20Wonderland.azw3
mobi file from https://filesamples.com/formats/mobi, from https://filesamples.com/samples/ebook/mobi/Sway.mobi To allow cross origin, it could be download from my site https://crossfireqq.cf/Sway.mobi
fb2 file from https://filesamples.com/formats/fb2, from https://filesamples.com/samples/ebook/fb2/Around%20the%20World%20in%2028%20Languages.fb2 To allow cross origin, it could be download from my site https://crossfireqq.cf/Around%20the%20World%20in%2028%20Languages.fb2
fb2.zip file from http://www.bibles.org.uk/The-British-Study-Edition-of-the-Urantia-Papers.fb2.zip To allow cross origin, it could be download from my site https://crossfireqq.cf/The-British-Study-Edition-of-the-Urantia-Papers.fb2.zip
cbz file from https://getcomics.info/dc/batgirls-14-2023/, from MEDIAFIRE
Can't test right now but I'm guessing that it fails when the mimetype is not set correctly? Probably one should set the name property for the Blob object from the url so it could detect the file type based on the file extension.
Can't test right now but I'm guessing that it fails when the mimetype is not set correctly? Probably one should set the name property for the Blob object from the url so it could detect the file type based on the file extension.
It‘s amazing that epub/azw/azw3/mobi files don't even need correct file extensions!
Kindle files are detected with magic bytes, so it always works.
It works for EPUBs, but I guess that's actually the bug. It assumes that the file is EPUB if it's a zip file and it isn't CBZ or FBZ. What it should do instead is to check the mimetype
file in the container.
Also, a better check for unzipped FB2 would be to first check the first few bytes for <?xml
. So probably needs to move the parseXML
function into reader.js
. First check whether its XML, then parse it, and then decide what to do with it depending on the name of the root element.
Kindle files are detected with magic bytes, so it always works.
It works for EPUBs, but I guess that's actually the bug. It assumes that the file is EPUB if it's a zip file and it isn't CBZ or FBZ. What it should do instead is to check the
mimetype
file in the container.Also, a better check for unzipped FB2 would be to first check the first few bytes for
<?xml
. So probably needs to move theparseXML
function intoreader.js
. First check whether its XML, then parse it, and then decide what to do with it depending on the name of the root element.
😳😳I don't know how to test it then.
Thank you for your awesome work, I can now read e-books in the browser without installing various software on my devices. But I still want to further request the api feature for read online ebooks, so that I can use one link to read the online e-books directly without download manually. I think the link could be like this https://johnfactotum.github.io/foliate-js/reader.html?file=`url-of-ebook`
It is very presumptuous to make such a request, but I think it is an important feature for an ebook reader in browser, and I‘m looking fordward to its coming.