1

我正在尝试创建一个书签应用程序来解析来自 Amazon、Etsy 和 JCrew 的信息并将其传输到内置于 Rails 中的愿望清单应用程序。我已经成功创建了一个书签按钮,将我的 javascript 文件加载到 DOM 中,但它似乎没有正确执行并将数据传递给我的应用程序。或者也许我的 javascript 有问题。谁能帮我弄清楚我做错了什么?我在下面包含了我的 js 文件:

function() {

function get_amazon_product_info() 
    {
        var title_span = document.getElementById("btAsinTitle");
        var title = title_span.innerText;

        var image_tag = document.getElementById("main-image");
        var image = image_tag.getAttribute("src");

        var price_span = document.getElementById("actualPriceValue");
        var price = price_span.innerText;

        var product_info = {
            title: title,
            image: image,
            price: price
        }
        return product_info
    }

function get_etsy_product_info()
{
        var title_span = document.getElementById("item-title");
        var title = title_span.innerText;

        var image_div = document.getElementById("fullimage_link1");
        var image_tag = image_div.getElementsByTagName("img");
        var image = image_tag[0].getAttribute("src");

        var price_div = document.getElementsByClassName("item-price");
        var price_span = price_div[0].getElementsByClassName("currency-value")
        var price = price_span[0].innerText;

        var product_info = {
            title: title,
            image: image,
            price: price
        }
        return product_info
}

function get_jcrew_product_info()
{
    var title_span = document.getElementById("pdp-title");
        var title = title_span.innerText;

        var image_div = document.getElementsByClassName("prod_main_img");
        var image_tag = image_div[0].getElementsByTagName("img");
        var image = image_tag[0].getAttribute("src");

        //lame implementation -- need to be able to determine which radio button is checked. Finish later!

        var price_div = document.getElementsByClassName("pdp-shapes");
        var price_span = price_div[0].getElementsByClassName("price")
        var price = price_span[0].innerText;

        var product_info = {
            title: title,
            image: image,
            price: price
        }
        return product_info
}

function determine_params() 
{
        domain = document.domain;
        if (domain == 'www.amazon.com')
        {   
            get_amazon_product_info();
        }
        else if (domain == 'www.etsy.com')
        {
            get_etsy_product_info();
        }
        else if (domain == 'www.jcrew.com')
        {
            get_jcrew_product_info();
        }
}   

function send_data(product_info)
{           
    var link_url = document.URL;
    var http = new XMLHttpRequest();
    var url = "http://max-miller.local:3000/add_product";
    var params = "title=" + product_info[title] + "&image=" + product_info[image] + "&price=" + product_info[price] + "&link_url=" + link_url;
    http.open("POST", url , true);

    //Send the proper header information along with the request
    http.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
    http.setRequestHeader("Content-length", params.length);
    http.setRequestHeader("Connection", "close");

    http.onreadystatechange = function() {
        if(http.readyState == 4 && http.status == 200) {
            alert(http.responseText);
        }
    }

    http.send(params);
}

determine_params();
send_data(product_info);

}

4

3 回答 3

0

正如我在评论中指出的那样,我看到您的代码原样存在两个问题。

首先,你的闭包永远不会被执行——它实际上在语法上是不正确的。在浏览器的控制台中,这就是这个示例之间的区别:

function() { console.log('something'); }

和这个:

(function() { console.log('something'); })();

其次XMLHttpRequest只能在页面域的上下文中工作。(该脚本不会获得对其来源域的特殊权限。)因此,鉴于您的脚本的性质,它看起来不是max-miller.local:3000预期的执行域,并且请求将失败。

查看类似 JSONP的解决方案。

于 2013-04-18T20:29:50.877 回答
0

希望能帮助到你:

我从来没有像你一样发送过数据http.sed(data)

但是,每当我需要来自服务器的某些东西时,我都会在 head 部分创建一个脚本元素;

始终使用json.stringify,这可能是您的应用无法发送数据的原因之一

并且if (s.length >= 2000)在使用我的解决方案时也要小心,因为您无法通过 1 个请求发送/接收无限数据

像这样:

    function createElementScript(src)
    {

        var script = document.createElement("script");
        script.type = 'text/javascript';
        script.src = src;
        //console.log("SRC: "+src);
        var header = document.getElementsByTagName("head");
        header[0].appendChild(script);
    }

wheresrc创建如下:

var s = JSON.stringify({'url': location.href,
                                    'title': document.getElementById('linkbook_article_title').value,
                                    'description': document.getElementById('linkbook_article_textarea').value
                                });
                                if (s.length >= 2000) {
                                    alert('Payload length is over 2000, action may fail.');
                                }
                                createElementScript(apiURL + "/FollowProduct?input=" + encodeURIComponent(s));

我的整个书签,也许它可以帮助你改进你的;我使用了单例模式,只是为了确保如果用户多次单击小书签,我不会重新插入小书签,而且我还想封装所有数据

<?php if (false) { ?><script><?php } ?>
    var LinkbookClass = LinkbookClass ? LinkbookClass : function() {

        var assetsURL = '<?= $this->getAssetsUrl(); ?>';
        var apiURL = '<?= Yii::app()->createAbsoluteUrl($this->module->id . '/' . $this->id . '/'); ?>';
        var imgsList = new Array();
        var ImgsListImgID = 0;
        //all the images found on the webpage
        var images = 0;
        var imgsListHeightWidth = [];
        var isHighlighting = false;
        var versionStatus;
        var flag1 = false;
        var flag2 = false;
        var precedentObj = null;
        var overlay,
                current,
                handler;
        var extractHL;
        var name = false, price = false, image = false;
        //do we save logs ?
        var consoleLog = true;
        var version_popup;
        var f = function()
        {
            createElementScript(assetsURL + '/sizzle.js?x=<?= $this->module->params['interface_version']; ?>');
            createElementScript(assetsURL + '/xpath.js?x=<?= rand(1, 10000000); ?>');
            //LinkbookPluginCollection.run();

            var popupdividreset = "linkbookreset";
            var DOCreset = document.getElementById(popupdividreset);
            if (DOCreset != null) {
                return false;
            }

            var popupdivid = "linkbookdetails";
            var DOC = document.getElementById(popupdivid);
            if (DOC != null) {
                return false;
            }

            //load css file, force a reload/recache
            addCSS(assetsURL + '/linkbook.css?x=<?= rand(1, 10000000); ?>');
            var divreset = document.createElement("div");
            divreset.id = popupdividreset;
            var div = document.createElement("div");
            div.id = popupdivid;
            //this will highlight the DOM element that you are hovering
            var divhighlight = document.createElement("div");
            divhighlight.id = "overlayhighlightlinkbook";
            var divOutside = document.createElement("div");
            divOutside.id = "LinkbookOverlay";
            var divLinkbook = document.createElement("divCloseAffair");
            divLinkbook.id = "divLinkbook";
            var str = '<div id="divemptylinkbook"></div>';
            str += divForm('none', div.id, images);
            str += divLogin('none', div.id);
            str += divDetails('none', div.id);
            str += divSuccess('none', div.id);
            str += divBroken('none', div.id);
            div.innerHTML = str;
            divreset.appendChild(div);
            //not used anymore
            //document.body.insertBefore(divreset, document.body.firstChild);

            divOutside.innerHTML = "";
            //inserting the DOM div blank element imediatly after body tag
            divhighlight.innerHTML = "";
            divLinkbook.appendChild(divhighlight);
            divLinkbook.appendChild(divOutside);
            divLinkbook.appendChild(divreset);
            document.body.insertBefore(divLinkbook, document.body.firstChild);
        };
        function addCSS(url) {
            var headID = document.getElementsByTagName("head")[0];
            var cssNode = document.createElement('link');
            cssNode.type = 'text/css';
            cssNode.rel = 'stylesheet';
            cssNode.href = url;
            cssNode.media = 'screen';
            headID.appendChild(cssNode);
        }
        ;
        function divLogin(displayTarget, div_id)
        {

            return '<?php $this->renderHTMLtoJS('login', array('js' => array('displayTarget', 'div_id', 'assetsURL'))); ?>';
        }
        ;
        function divForm(displayTarget, div_id, images)
        {

            return '<?php $this->renderHTMLtoJS('form', array('js' => array('displayTarget', 'div_id', 'images', 'assetsURL'), 'url' => $url, 'follower' => $follower)); ?>';
        }
        ;
        function divBroken(displayTarget, div_id)
        {

            return '<?php $this->renderHTMLtoJS('report_broken_url', array('js' => array('displayTarget', 'div_id', 'assetsURL'))); ?>';
        }
        ;
        function divSuccess(displayTarget, div_id)
        {

            return '<?php $this->renderHTMLtoJS('success', array('js' => array('displayTarget', 'div_id', 'assetsURL'))); ?>';
        }
        ;
        function divDetails(displayTarget, div_id)
        {
            return '<?php $this->renderHTMLtoJS('details', array('js' => array('displayTarget', 'div_id', 'assetsURL'), 'url' => $url, 'follower' => $follower)); ?>';
        }
        ;
        function createElementScript(src)
        {

            var script = document.createElement("script");
            script.type = 'text/javascript';
            script.src = src;
            //console.log("SRC: "+src);
            var header = document.getElementsByTagName("head");
            header[0].appendChild(script);
        }
        ;
        function hideAllDivs() {
            var a = ['LinkbookParrentLogin', 'LinkbookParrentDetails', 'LinkbookParrentForm'];
            for (x in a) {
                var d = document.getElementById(a[x]);
                if (d) {
                    d.style.display = 'none';
                }
            }
        }
        ;
        function divGallery(displayTarget, div_id)
        {
            return '<?php $this->renderHTMLtoJS('gallery', array('js' => array('displayTarget', 'div_id', 'assetsURL'))); ?>';
        }
        ;
        f.prototype = {
            labelEdit: function()
            {
                if (document.getElementById('form_selected_product_name_Linkbook_input').style.display == 'none')
                {
                    document.getElementById('form_selected_product_name_Linkbook_input').style.display = document.getElementById("divemptylinkbook").style.display;
                    document.getElementById('form_selected_product_name_Linkbook_span').style.display = 'none';
                    document.getElementById('Linkbook_labelEdit').style.display = 'none';
                    document.getElementById('form_selected_product_name_Linkbook_input').value = document.getElementById('form_selected_product_name_Linkbook_span').innerHTML;
                    document.getElementById('form_selected_product_name_Linkbook_input').focus();
                }
            },
            get_article_title: function()
            {
                if (document.title)
                    document.getElementById('linkbook_article_title').value = document.title;
                else
                    document.getElementById('linkbook_article_title').value = location.href;
            },
            get_article_description: function()
            {
                if (document.getElementsByName('description')[0])
                {
                    if (document.getElementsByName('description')[0].getAttribute('content'))
                        document.getElementById('linkbook_article_textarea').value = document.getElementsByName('description')[0].getAttribute('content');
                    else
                        document.getElementById('linkbook_article_textarea').value = 'null';
                }
                else
                    document.getElementById('linkbook_article_textarea').value = 'null';
            },
            init_after_login: function(is_product)
            {
                this.showDiv('LinkbookParrentForm');
            },
            init: function() {
                //console.log('init');
                this.get_article_title();
                this.get_article_description();
                if (<?php
    if (Yii::app()->user->isGuest)
        echo 'true';
    else
        echo 'false';
?>) {
                    this.showDiv('LinkbookParrentLogin');
                } else {

                    Linkbook.init_after_login(<?php
    if (empty($product))
        echo 'false';
    else
        echo 'true';
?>);
                }
            },
            showDiv: function(divId) {
                var d = document.getElementById(divId);
                if (d) {
                    hideAllDivs();
                    d.style.display = document.getElementById("divemptylinkbook").style.display;
                }
            },
            actionSubmit: function(formID, e)
            {
                //alert(formID+'click');
                if (formID == 1)
                    Linkbook.outBound("login");
                if (formID == 2)
                    Linkbook.outBound("follow");
                e.preventDefault();
            },
            toggleItem: function(id) {
                var item = document.getElementById(id);
                if (item) {
                    var parent = item.parentNode;
                    parent.removeChild(item);
                }
            },
            hideDivs: function() {
                hideAllDivs();
            },
            //all the data that has been send from the server to the bookmarlet passed thru this method
            //inBound has 2 parameters, because we need to know the action and the result value
            inBound: function(action, data)
            {

                try {
                    //console.log(data);
                    if (parseInt(data.code) < 0) {
                        //system error
                        alert('Internal error!');
                        return;
                    }
                    switch (action)
                    {
                        case 'login':
                            //console.log('data code: '+data.code);
                            if (data.code != 0) {
                                // show error
                                document.getElementById('LinkbookLoginError').innerHTML = data.message;
                            } else {
                                //console.log(data.login.json_order);
                                //repopulating plugin collection after login action;
                                //LinkbookPluginCollection.cleanup();//cleanup needed
                                //LinkbookPluginCollection.order = data.login.json_order;//repopulation
                                //LinkbookPluginCollection.run();
                                //console.log('new data'+data.login.product);
                                //this.showDiv('LinkbookParrentForm');
                                //console.log(data.login.product.product_name && data.login.product.product_name.length>0);
                                Linkbook.init_after_login(data.login.product.product_name && data.login.product.product_name.length > 0);
                            }
                            break;
                        case 'logout':
                            hideAllDivs();
                            this.showDiv('LinkbookParrentLogin');
                            break;
                        case 'bookmarklet':
                            alert('Bookmarklet error');
                            break;
                        case 'follow':
                            if (data.code != 0)
                            {
                                document.getElementById('form_error_Linkbook').innerHTML = data.message;
                            }
                            else
                            {
                                this.showDiv('LinkbookParrentSuccess');
                            }
                            break;
                        default:
                            alert('Unknown inBound action: ' + action);
                            break;
                    }
                } catch (err) {
                    if (consoleLog) {
                        //console.log(err.toString());
                    }
                    alert('Something went wrong, server returned invalid message!');
                }
            }, //end f inBound()
            //method used to transfer the data from the bookmarklet to the server
            //outBound needs to know only the action, the parameters will be contructed, ex. : ?action=x&...
            outBound: function(action)
            {
                try {
                    switch (action)
                    {//start switch
                        case 'logout':
                            createElementScript(apiURL + '/MakeLogout');
                            break;
                        case 'login':
                            if (document.getElementById("form_remember").value == 'on')
                                form_remember_Linkbook = 1;
                            else
                                form_remember_Linkbook = 0;
                            createElementScript(apiURL + '/MakeLogin/email/' + document.getElementById("form_email").value + '/password/' + document.getElementById("form_password").value + '/remember/' + form_remember_Linkbook + '?url=' + encodeURIComponent(location.href));
                            break;
                        case 'follow':
                            if (true)
                            {
                                //document.getElementById('form_error_Linkbook').innerHTML = '';
                                var s = JSON.stringify({'url': location.href,
                                    'title': document.getElementById('linkbook_article_title').value,
                                    'description': document.getElementById('linkbook_article_textarea').value
                                });
                                if (s.length >= 2000) {
                                    alert('Payload length is over 2000, action may fail.');
                                }
                                createElementScript(apiURL + "/FollowProduct?input=" + encodeURIComponent(s));
                            } else {
                                // put error message on screen
                                document.getElementById('form_error_Linkbook').innerHTML = 'error';
                            }
                            break;
                        case 'report_broken_url':
                            this.showDiv('LinkbookParrentBroken');
                            //var s = JSON.stringify(LinkbookPluginCollection);
                            if (s.length >= 2000) {
                                alert('Payload length is over 2000, action may fail.');
                            }
                            createElementScript(apiURL + "/ReportBrokenUrl?input=" + encodeURIComponent(s));
                            break;
                        default:
                            alert('Unknown outBound action: ' + action);
                            break;
                    }//end switch
                }
                catch (err) {
                    if (consoleLog) {
                        //console.log(err.toString());
                    }
                    alert('Something went wrong, couldn\'t prepare data!');
                }


            }//end f outBound()
        }
        return f;
    }();
    var Linkbook = new LinkbookClass();
    Linkbook.init();
于 2013-04-18T20:13:23.973 回答
0

您是否在服务器上设置了 CORS 权限?

http://en.wikipedia.org/wiki/Cross-origin_resource_sharing

http://enable-cors.org/

如果没有,您的 AJAX 将由于同源策略而失败。

http://en.wikipedia.org/wiki/Same_origin_policy

于 2013-04-19T04:01:59.310 回答