我正在尝试创建一个书签应用程序,用于解析来自Amazon,Etsy和JCrew的信息,并将其传输到Rails中构建的wishlist应用程序。我已经成功创建了一个书签按钮,将我的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);
}
答案 0 :(得分: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);
}
创建src
,如:
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();
答案 1 :(得分:0)
正如我的评论中所述,我在您的代码中看到了两个问题 as-is 。
首先,你的闭包永远不会被执行 - 它实际上在语法上是不正确的。在浏览器的控制台中,这是示例之间的区别:
function() { console.log('something'); }
这一个:
(function() { console.log('something'); })();
第二次,XMLHttpRequest
只能在网页的上下文中使用。 (该脚本不会从它所来自的域获得特殊权限。)因此,鉴于您的脚本的性质,max-miller.local:3000
预期的域名执行,请求将失败。
查看JSONP - 就像解决方案一样。
答案 2 :(得分:0)