Google 自定义搜索 - 从 url 参数手动加载/执行
-
12-12-2019 - |
题
从谷歌自定义搜索中得到一些奇怪的行为,我似乎无法弄清楚。也许有人有线索。
我正在建立一个 Magento 网站,它有自己的内部搜索引擎 - 但仅限于产品。我也想在搜索结果页面上实现谷歌自定义搜索结果。我认为我应该能够简单地根据网址中的查询变量执行搜索(以返回所有非产品内容),如下所示:
<section style="min-height:600px">
<div style="background-color:#DFDFDF; min-height:800px; width:100%;">
<div id="cse">Loading</div>
</div>
<script src="http://www.google.com/jsapi" type="text/javascript"></script>
<script type="text/javascript">
//<![CDATA[
$(document).ready( function(){
console.log('search initiated');
var t = window.setTimeout( function(){ customSearch(); }, 5000 );
});
function customSearch(){
var q = urlParams()['q'];
if (q != undefined && q != ""){
console.log('q : %s', q); //outputs successfully
google.load('search', '1');
google.setOnLoadCallback(function () {
var customSearchControl = new google.search.CustomSearchControl(MY CUSTOM ID KEY);
var cseDrawOptions = new google.search.DrawOptions();
cseDrawOptions.setAutoComplete(true); //unknown if this is required...
customSearchControl.draw('cse',cseDrawOptions);
customSearchControl.execute(q);
}, true);
}
}
function urlParams(){
var vars = [];
var hash;
var index = window.location.href.indexOf('?');
if( index != -1 ){
var hashes = window.location.href.slice(index + 1).split('&');
for(var i = 0; i < hashes.length; i++){
hash = hashes[i].split('=');
vars.push(hash[0]);
vars[hash[0]] = hash[1].replace(/\+/g, " ");
}
}
return vars;
}
//]>
</script>
</section>
我会注意到,我已经从逻辑中提取了所有其他内容(但它在 magento 中的实现是相同的)。
所以行为是这样的:页面加载正常(出于测试目的,我通过超时延迟了谷歌搜索)。假设 url 中有一个查询 var,控制台会按预期跟踪。然后页面就被删除了,谷歌没有返回任何内容。“歼灭”...这意味着页面上的所有元素都会消失,或者被谷歌加载的新页面覆盖。就好像搜索控件没有创建 iframe - 它只是将页面替换为 <body>
-less html 页面。
我已经准备了很多关于这个主题的文章,并回顾了 应用程序编程接口 - 这段代码看起来应该可以工作。但显然不是。
我缺少什么?
干杯-
更新
继续搞乱这个问题表明,无论出于何种原因:
google.load('search', '1');
google.google.setOnLoadCallback( console.log('loaded') )
是导致页面替换问题的原因。然而,响应的页面包含指向谷歌托管的搜索模块的链接。如果我手动链接这些文件(放弃 google.load
)然后我可以按预期运行搜索:
<script src="http://www.google.com/jsapi" type="text/javascript"></script>
<script src="http://www.google.com/uds/?file=search&v=1" type="text/javascript"></script>
<script type="text/javascript">
//<![CDATA[
... search logic
然后我发现了一种替代语法 谷歌开发者 页面似乎按预期工作:
$(document).ready( function(){
google.load("search", "1", {"callback" : customSearch});
});
function customSearch(){
var q = urlParams()['q'];
if (q != undefined && q != ""){
var cseControl = new google.search.CustomSearchControl('MY CUSTOM KEY');
var cseDrawOptions = new google.search.DrawOptions();
cseDrawOptions.enableSearchResultsOnly()
cseControl.draw('cse', cseDrawOptions);
cseControl.execute(q);
}
}
哪个按预期工作。此时唯一真正的问题是主机
Unsafe JavaScript attempt to access frame with URL http://mydomain from frame with URL http://www.google/cse?...
现在它被抛出了。
我不知道加载语法的两个不同版本如何改变任何东西......但似乎是的。无论如何,我不清楚如何解决这些跨域错误。
想法会很棒。
解决方案
没什么吧?
嗯 - 我基本上已经找到了一个很好的解决方案,使用了另一种方法,我认为从长远来看,这种方法会更加灵活。使用谷歌 RESTful API 和简单的jquery .ajax
调用,我可以获得良好的、可控的结果,并且没有跨域错误:
<div id="cse">Loading</div>
<script>
//https://developers.google.com/custom-search/v1/getting_started
//https://developers.google.com/custom-search/v1/using_rest#query-params
//https://developers.google.com/custom-search/v1/cse/list
var _url = "https://www.googleapis.com/customsearch/v1";
var _key = 'AIzaSy... your api key here';
var _cx = '001809... your engine id';
var _q = urlParams()['q']; //query param
jQuery(document).ready(function() {
$j.ajax({
url : _url,
type : 'GET',
dataType : 'jsonp',
data :{
key : _key,
cx : _cx,
q :_q
},
success : function(data, textStatus, jqXHR){ responseHandler(data); },
error : function(jqXHR, textStatus, errorThrown){ console.log('error: %s'), errorThrown},
beforeSend : function(){ console.log('sending request')},
crossDomain : true
});
});
function responseHandler( response, status) {
console.log(response);
var cse = $j('#cse'); // render vars as needed...
for (var i = 0; i < response.items.length; i++) {
var item = response.items[i];
cse.append( "<br>" + item.htmlTitle);
}
}
function urlParams(){
var vars = [];
var hash;
var index = window.location.href.indexOf('?');
if( index != -1 ){
var hashes = window.location.href.slice(index + 1).split('&');
for(var i = 0; i < hashes.length; i++){
hash = hashes[i].split('=');
vars.push(hash[0]);
vars[hash[0]] = hash[1];
}
}
return vars;
}
</script>
你也可以;D
干杯