Open louie0086 opened 9 months ago
Hey, louie
I don't think Strict-Transport-Security
is relevant here. "CSP" is short for "Content Security Policy".
This package uses WebAssembly to provide the core function of detecting barcodes. And the browser must instantiate and execute the WebAssembly module to use it. However, per the spec, websites can control whether to block the WebAssembly execution by setting the script-src
directive in CSP, specifically the wasm-unsafe-eval
or unsafe-eval
source value. If it is blocked, the error Barcode detection service unavailable
will get thrown.
The directive connect-src
can also affect this package. To prevent bloating the size, this package will load the .wasm
file from the cdn.jsdelivr.net
CDN at runtime (using fetch
). connect-src
or default-src
can restrict the URLs which can be loaded with fetch
. So if this connection is somewhat get blocked, the service unavailable
error will also be thrown.
There're corresponding ways in which you can solve this problem:
wasm-unsafe-eval
. and make sure connect-src
or default-src
includes https://cdn.jsdelivr.net
. A detailed explanation can be found at https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy.wasm
file from a CDN. You can use setZXingModuleOverrides
exported by vue-qrcode-reader
to change the location where the .wasm
file is hosted. For example, you can host the file on your website as an asset, etc.If neither solves your problem, it would be great if you can provide the malfunctioning website so that I can dig into it and check whether there're some other bugs to fix.
import wasmFile from "../node_modules/@sec-ant/zxing-wasm/dist/reader/zxing_reader.wasm?url";
I would like to ask what the syntax (?url)is?
in vue-cli project
import wasmFile from "@sec-ant/zxing-wasm/dist/reader/zxing_reader.wasm?url";
it's show error:
* a in ./node_modules/@sec-ant/zxing-wasm/dist/reader/zxing_reader.wasm?url
To install it, you can run: npm install --save a
How do I import the wasm module correctly?
Ok you decide not to fetch the .wasm
file from jsDelivr. There're some gotchas, so I'd like to explain more:
First, a question: I wonder if you want to inline the .wasm
file inside your script output files or you want to host it as a binary file on your site, and fetch it from your site at runtime?
Inlining means encoding the .wasm
file as a Base64 data url and hardcode this data url inside your script files. If you use a syntax like this:
import wasmFile from "...?url"
then you're inlining it. ?url
is a syntax provided by build tools, like Vite, to transform assets into data urls. I'm not sure if vue-cli
supports it. If it is supported, then the wasmFile
will be a huge base64 encoded data url.
Afterwards, you use setZXingModuleOverrides
+ locateFile
to relocate the fetching path to this data url:
setZXingModuleOverrides({
locateFile: (path, prefix) => {
if (path.endsWith(".wasm")) {
return wasmFile; // <= a huge Base64 encoded data url
}
return prefix + path;
},
});
A data url occupies a larger space than its binary form, and parsing a data url into binary data also consumes more CPU clocks. So, ideally, I suggest you to not use the inline form.
If you want to host it as a binary file on your site, then you need not to import it. You can just copy the .wasm
file to your website's assets folder, e.g. public
or assets
, and use setZXingModuleOverrides
+ locateFile
to relocate the fetching path like this:
setZXingModuleOverrides({
locateFile: (path, prefix) => {
if (path.endsWith(".wasm")) {
return "https://<your website host>/public/zxing_reader.wasm"; // <= where the .wasm file is at
}
return prefix + path;
},
});
Either way, CSP still applies. You have to make sure content-src
and script-src
are correctly configured to allow you fetching and executing it.
Second question: where is the .wasm
file?
Normally, when you add vue-qrcode-reader
as a dependency in your project, it will also download its dependencies inside node_modules
folder, which includes barcode-detector
. And barcode-detector
in turn will download its dependency @sec-ant/zxing-wasm
. This process is handled by the package manager automatically so you don't need to worry.
The .wasm
file is published as an asset included in the package @sec-ant/zxing-wasm
, therefore, the .wasm
file can be found at this path:
<project root>/node_modules/@sec-ant/zxing-wasm/dist/reader/zxing_reader.wasm
BUT, I made a mistake not pinning the version. So, the .wasm
file you found in <project root>/node_modules/@sec-ant/zxing-wasm
may not be what vue-qrcode-reader
expects (Sorry for this mistake, I'm going to fix this in the next version). Therefore, for now, I recommend you manually download the .wasm
file with the correct version, from the CDN.
If you're using vue-qrcode-reader@v5.3.4
, the matching version is @sec-ant/zxing-wasm@2.1.3
, so you can download the zxing_reader.wasm
file from any of the following CDN paths:
Once you've downloaded the correct version of the .wasm
file, you can inline or host it as you wish in your project.
Again, I'm really sorry for the inconvenience. Once the version problem is fixed and released in vue-qrcode-reader
, you won't have to worry about downloading it with the matching version. You can just import or copy it from <project root>/node_modules/@sec-ant/zxing-wasm/dist/reader/zxing_reader.wasm
.
Thank @Sec-ant
i just put zxing_reader.wasm
at assets public folder and then
setZXingModuleOverrides({
locateFile: (path, prefix) => {
if (path.endsWith(".wasm")) {
return '/zxing_reader.wasm';
}
return prefix + path;
},
});
my project site can request zxing_reader.wasm now.but it's still has error "Barcode detection service unavailable. Use 'setZXingModuleOverrides' in offline or strict CSP environments."
if the zxing_reader.wasm
not from CDN and CSP not configured .Is this error still here?
Then this may be some other bug. To solve this problem I'll need more information.
If this issue is OS/browser related
For example, is the demo page of vue-qrcode-reader works on the same device? If it doesn't, then it's probably device related, and then I need the versions of the device's OS and browser.
If the error only occurs in your project site
Then it would be very helpful for you to share a repo to let me reproduce this problem, or share your site so that I can debug.
Then this may be some other bug. To solve this problem I'll need more information.
- If this issue is OS/browser related For example, is the demo page of vue-qrcode-reader works on the same device? If it doesn't, then it's probably device related, and then I need the versions of the device's OS and browser.
- If the error only occurs in your project site Then it would be very helpful for you to share a repo to let me reproduce this problem, or share your site so that I can debug.
yes.same device. vue-qrcode-reader demo page no exception
In that case, can you share a repro :)
In that case, can you share a repro :)
Ok .i send email to you
Ok .i send email to you
Alright, here's my email address: zzwu@zju.edu.cn
@louie0086 Can you try vue-qrcode-reader@5.3.5
(matches with @sec-ant/zxing-wasm@2.1.5
) and see if this error still exists? If the error still exists, can you find more error information in the console?
@louie0086 Can you try
vue-qrcode-reader@5.3.5
(matches with@sec-ant/zxing-wasm@2.1.5
) and see if this error still exists? If the error still exists, can you find more error information in the console?
i updated @sec-ant/zxing-wasm@2.1.5 and copy zxing_reader.wasm to zxing_reader1.wasm
still
setZXingModuleOverrides({
locateFile: (path, prefix) => {
if (path.endsWith(".wasm")) {
return '/zxing_reader1.wasm';
}
return prefix + path;
},
});
now it show
"Barcode detection service unavailable.",
"NotSupportedError"
I added this line of code to log a detailed error information, can you some how see this in the console?
I added this line of code to log a detailed error information, can you some how see this in the console?
The RangeError is what we've been seeking. Is that just an empty object or does it hold more information?
![]()
The RangeError is what we've been seeking. Is that just an empty object or does it hold more information?
message:Range consisting of offset and length are out of bounds.
stack:set@[native code]
Hmm, interesting.
If this is something about the WebAssembly instantiation, I wonder why vue-qrcode-reader
demo page works.
Does this error message have a context so that I can check which line of code and file this error is thrown from? Or can you jump to the corresponding file and provide some information on its whereabouts? Screenshots would be great, and you can email me if you want.
PS: I previously said
Once the version problem is fixed and released in vue-qrcode-reader, you won't have to worry about downloading it with the matching version. You can just import or copy it from
/node_modules/@sec-ant/zxing-wasm/dist/reader/zxing_reader.wasm.
The good news is, starting from vue_qrcode_reader@5.3.5
, this version problem is fixed :).
I isolated a stripped down code from my project that is scannable. But the original project still has Range Error and NotSupportedError.
https://github.com/louie0086/test_Barcode
i used mkcert and http-server -S -C {PATH/TO/CERTIFICATE-FILENAME}.pem -K {PATH/TO/CERTIFICATE-KEY-FILENAME}.pem
https://web.dev/i18n/en/how-to-use-local-https/
with local IP test
Thanks for the repo, but I'm afraid a scannable demo can't provide to too much information on why your original project doesn't work.
What about these questions I previously asked:
Does this error message have a context so that I can check which line of code and file this error is thrown from? Or can you jump to the corresponding file and provide some information on its whereabouts?
RangeError stack here:
$.HEAP8.set(O, L)
RangeError stack here:
$.HEAP8.set(O, L)
Thanks, this is very helpful. So the error is thrown from this line from the source code:
https://github.com/Sec-ant/zxing-wasm/blob/8b8df68e781e7524ce96f12276c7a028b2c0c9d6/src/core.ts#L390
I'm not very clear about the root cause but I can try to do some debugging. So this error happens on an iPhone iOS 16.6 Safari Browser, right?
RangeError stack here: https://github.com/louie0086/test_Barcode/blob/5c7a69936a4649c5b860b405b6797ba5aef3456c/public/barcode-detector/dist/es/pure.js#L345-L354
$.HEAP8.set(O, L)
Thanks, this is very helpful. So the error is thrown from this line from the source code:
https://github.com/Sec-ant/zxing-wasm/blob/8b8df68e781e7524ce96f12276c7a028b2c0c9d6/src/core.ts#L390
I'm not very clear about the root cause but I can try to do some debugging. So this error happens on an iPhone iOS 16.6 Safari Browser, right?
yes.iPhone 14 Pro Max.
But the demo repo is Okay
Can you log the data
, byteLength
, bufferPtr
and HEAP8
if you can patch the source packages in your project?
You can also directly modify the dist file, like this:
And show me the result?
What's the byteLength
of the Int8Array
, i.e. zxingInstance.HEAP8.byteLength
?
byteLength
i just console at barcode-detector.pure.js
const w = await Bt($, ot.getState().zxingModuleOverrides),
{
data: O,
width: G,
height: j,
data: { byteLength: F },
} = c,
Y = w._malloc(F)
console.log('data:',O)
console.log('byteLength:',F)
console.log('bufferPtr:',Y)
console.log('zxingInstance.HEAP8:',w.HEAP8)
w.HEAP8.set(O, Y)
const N = w.readBarcodesFromPixmap(Y, G, j, m, pe(u), g)
w._free(Y)
I mean, can you also log the byteLength
of the HEAP8
object in the console? So I can know the total available memory it holds.
like this (add this line):
console.log('zxingInstance.HEAP8.byteLength:', w.HEAP8.byteLength);
w.HEAP8.byteLength
the result: zxingInstance.HEAP8.byteLength:0
That's some useful info and a good start. Apparently, for some reason, the memory is not successfully allocated, which brings us to this line of code:
Can you help me check whether J.buffer.byteLength
is also zero?
That's some useful info and a good start. Apparently, for some reason, the memory is not successfully allocated, which brings us to this line of code:
Can you help me check whether
J.buffer.byteLength
is also zero?
https://github.com/louie0086/test_Barcode/blob/master/barcode-detector.pure_4.js#L443
K.buffer undefiend
Hmmm, that means wasmMemory
is not initiated.
Can you log n
, n.exports
and n.exports.qa
in this function before the return
statement?
In a normal case, the n.exports.qa
should be an instance of WebAssembly.Memory
, like this (in a chrome browser):
I cannot tell whether B$()
in your snapshot is an instance of the WebAssembly.Memory
or is just a plain function. Given that the code works in your demo repo but not in your project, can you also check the n.exports.qa
in your demo repo and compare the working one with the error one to see if the difference indeed lies in the n.exports.qa
?
https://github.com/louie0086/test_Barcode/blob/master/barcode-detector.pure_4.js#L564-L566
i add a alert
The demo tips [object WebAssembly.Memory]
but the project is function B$(){hC()}
https://github.com/Sec-ant/barcode-detector/blob/ab876a6a19b610ed3ce4b69f8216ed3c878421f4/src/BarcodeDetector.ts#L140-L143
i used vue-qrcode-reader at https website
it shows
"Barcode detection service unavailable. Use 'setZXingModuleOverrides' in offline or strict CSP environments.", "NotSupportedError"
the host already set
Strict-Transport-Security: max-age=31536000; includeSubdomains; preload
but the static js file not set
i see the demo website https://vue-qrcode-reader.netlify.app. it's doc and static js both set Strict-Transport-Security
how can i solve the detect error?