简体   繁体   中英

Using zxing Barcode Scanner within a web page

Is there a working example how you can use the zxing Barcode Scanner from a web page?

Referring to this documentation: https://github.com/zxing/zxing/wiki/Scanning-From-Web-Pages

shouldn't the following test code work?

 function Test1() { $.ajax( { url: "zxing://scan/?ret=http%3A%2F%2Ffoo.com%2Fproducts%2F%7BCODE%7D%2Fdescription&SCAN_FORMATS=UPC_A,EAN_13", success:function() { alert("success"); }, error:function() { alert("error"); } }); } function Test2() { $.ajax( { url: "http://zxing.appspot.com/scan?ret=http%3A%2F%2Ffoo.com%2Fproducts%2F%7BCODE%7D%2Fdescription&SCAN_FORMATS=UPC_A,EAN_13", success:function() { alert("success"); }, error:function() { alert("error"); } }); } 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script> <button id="button1" onClick="Test1();">Test 1</button> <br> <br> <button id="button2" onClick="Test2();">Test 2</button> 

I keep getting "error" on my Android 4.4.2 Samsung Galaxy TabPro and Samsung Galaxy S4. I've tried the stock browser, Chrome, Firefox and Dolphin Browser.

Even http://zxing.appspot.com/scan doesn't work as it always asks me to install the (already installed) app.

Any help would be much appreciated.

ZXing isn't designed to work with AJAX. Instead, it works by opening a parsed URL in the default browser. The behavior of the browser is mainly what's responsible for the user experience from that point forward.

There are several methods posted regarding this; unfortunately, there is no one method that will work for every browser.

Some browsers, when you open them from the command line, will check to see if the URL is already opened in another tab, and if so, will use that tab instead of a new one. This will cause a "onhashchange" event if the zxing link contains "zxing://scan/?ret=mytab.html#{CODE}".

Other browsers don't perform such a check, so we wind up with multiple tabs, all having the same URL (with the exception of the hash), and none of them raising the "hashchanged" event. For those browsers, we need to re-use the page from cache if possible (to prevent network traffic on every scan), and change the localStorage value to what the hash is. If the browser is capable of listening for the "storage" event, we can use that to trigger the code.

The code below works with Chrome, the intrinsic Android browser, and Firefox. It might work with others, but I haven't tried. One Firefox caveat, though, is that the scanner window will only close if the about:config setting "dom.allow_scripts_to_close_windows" is set to "true".

** This was edited to work better with multiple pages that allow scans, and now you can use have different hashes without interfering with the code. **

NEW VERSION 12/19/16

<!DOCTYPE html>
<HTML>
<HEAD>
<script type="text/javascript">

    if(window.location.hash.substr(1,2) == "zx"){
        var bc = window.location.hash.substr(3);
        localStorage["barcode"] = decodeURI(window.location.hash.substr(3))
        window.close();
        self.close();
        window.location.href = "about:blank";//In case self.close isn't allowed
    }
</script>
<SCRIPT type="text/javascript" >
    var changingHash = false;
    function onbarcode(event){
        switch(event.type){
            case "hashchange":{
                if(changingHash == true){
                    return;
                }
                var hash = window.location.hash;
                if(hash.substr(0,3) == "#zx"){
                    hash = window.location.hash.substr(3);
                    changingHash = true;
                    window.location.hash = event.oldURL.split("\#")[1] || ""
                    changingHash = false;
                    processBarcode(hash);
                }

                break;
            }
            case "storage":{
                window.focus();
                if(event.key == "barcode"){
                    window.removeEventListener("storage", onbarcode, false);
                    processBarcode(event.newValue);
                }
                break;
            }
            default:{
                console.log(event)
                break;
            }
        }
    }
    window.addEventListener("hashchange", onbarcode, false);

    function getScan(){
        var href = window.location.href;
        var ptr = href.lastIndexOf("#");
        if(ptr>0){
            href = href.substr(0,ptr);
        }
        window.addEventListener("storage", onbarcode, false);
        setTimeout('window.removeEventListener("storage", onbarcode, false)', 15000);
        localStorage.removeItem("barcode");
        //window.open  (href + "#zx" + new Date().toString());

        if(navigator.userAgent.match(/Firefox/i)){
            //Used for Firefox. If Chrome uses this, it raises the "hashchanged" event only.
            window.location.href =  ("zxing://scan/?ret=" + encodeURIComponent(href + "#zx{CODE}"));
        }else{
            //Used for Chrome. If Firefox uses this, it leaves the scan window open.
            window.open   ("zxing://scan/?ret=" + encodeURIComponent(href + "#zx{CODE}"));
        }
    }

    function processBarcode(bc){
        document.getElementById("scans").innerHTML += "<div>" + bc + "</div>";
        //put your code in place of the line above.
    }

</SCRIPT>
<META name="viewport" content="width=device-width, initial-scale=1" />
</HEAD>
<BODY>
<INPUT id=barcode type=text >
<INPUT style="width:100px;height:100px" type=button value="Scan" onclick="getScan();">
<div id="scans"></div>
</BODY>
</HTML>

You can make a JS include file for the top block of script, and include it on all the pages where you need scanning capabilities.

Then in the body of your document, you can set an event somewhere to call getZxing(), which will call processBarcode(barcode) that you write into your page. Included is a simple one for example's sake.

Side Note : The first time you run zxing from your page, you'll be asked to choose a default app. Make sure you chose the same browser that you're running the page from. Additionally, if you previously selected a default broswer for zxing and want to change which browser you use for zxing, you'll need to clear defaults from your other browsers.

Many thanks to @sean-owen for his hard work and fantastic product.

UPDATE 12/19/16

Ok, I did a slightly more robust version that works well with Firefox and Chrome. A couple of things I discovered:

Chrome will use the Storage event if the scanner is not set to open Chrome automatically, and will use the Hash event after it becomes default.

Firefox will never use the Hash event, but opens an extra window unless you call the scanner with window.location.href (Thanks, @Roland)

There are a couple of other anomalies, but no deal breakers.

I left the "zx" prefix in the hash, so that the code could delineate between scanner hashes and regular hashes. If you leave it in there, you'll not notice it in the processBarcode function, and non-zx hashes will operate as expected.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM