移花接木之真假baidu

1 界面搭建

界面元素包括logo图片、搜索框和搜索按钮。通过css和HTML创建:
这里写图片描述
代码如下:

<style>
    *{margin:0;padding:0;}
    body
    {
        background:#99eab9
    }

    img,input,button{display:block;margin:auto}

    ul{list-style:none;}

    a{text-decoration:none;}

    #logo
    {

        width:270px;
        height:129px;
        margin-top:50px;

        display:block;
    }
    #searchDiv
    {       
        width: 641px;
        height: 34px;
        margin:  auto;
        margin-top:15px;

    }
    #searchText
    {
        width:537px;
        height:30px;
        float:left
    }
    #button
    {
        width:100px;
        height:34px;
        text-align:center;
        font-size:16px;
        cursor:pointer;

    }
    #keyContainer
    {
        width: 641px;
        margin:auto;
    }
    #keyWords
    {
        width:539px;
        border:1px solid #575757;
        line-height:30px;
        display:none;
    }
    #keyWords ul li
    {
        cursor:pointer;
    }
    #keyWords ul li:hover
    {
        background:#cacaca;
    }
</style>

</head>

<body>
<img id="logo" src="./images/baidu.png" />
<div id = "searchDiv">
    <span>
        <input type="text" id="searchText"/>
        <button id="button">百度一下</button>
    </span>
</div>
<div id="keyContainer">
    <div id="keyWords">
        <ul id="key">
        </ul>
    </div>
</div>
</body>

2 搜索服务

每次输入关键词进行搜索百度都会给出一些关键词联想,例如我们搜索JavaScript,则会出现下面的页面形式:
这里写图片描述
我们通过在Chrome中抓包发现,当输入关键词时会产生一次请求,请求链接如下:

https://sp0.baidu.com/5a1Fazu8AA54nxGko9WTAnF6hhy/su?wd=JavaScript&json=1&p=3&sid=1423_21110_26923_20928&req=2&bs=111&pbs=111&csor=10&pwd=jav&cb=jQuery110204138693140994414_1534129815131&_=1534129815189

该请求的响应为:

jQuery110204138693140994414_1534129815131({"q":"javascript","p":false,"bs":"111","csor":"10","status":0,"g":[ { "q": "javascript学习指南", "t": "n", "st": { "q": "javascript学习指南", "new": 0 } }, { "q": "href=jacascript::void(0)", "t": "n", "st": { "q": "href=jacascript::void(0)", "new": 0 } }, { "q": "js高级程序设计第三版 pdf", "t": "n", "st": { "q": "js高级程序设计第三版 pdf", "new": 0 } } ],"s":["javascript学习指南","href=jacascript::void(0)","js高级程序设计第三版 pdf"]});

可以看到返回的对象s属性里的内容正是联想到的关键词!而该部分的头部正好对应于请求链接的cb参数,且当我们修改了可以发现cb参数对应的值时,响应对象的头部也会对应发生变化。请求查询的参数中只有wdcb两个参数是真正有用的。wd参数对应于用户输入的关键词,cb参数则是一个回调函数,该函数包含一个参数,是一个对象,联想关键词信息就保存在该对象的s属性里。
因此,我们只要修改请求链接的wdcb参数并在浏览器中输入该链接即可得到相应的百度搜索的联想关键词。例如设置wd参数值为vue,得到的联想关键词与在百度搜索中得到的结果是一样的:
这里写图片描述
这里写图片描述
那么,我们只要在搜索框输入内容时,将输入内容赋给wd参数,然后调用一次该链接就可以了。
但是,浏览器一般是不允许跨域访问的,我们怎么能在自己建立的搜索页面中去跨域访问百度搜索呢?
其实,虽然不能跨域访问,但是可以引入外部脚本,即通过<script>标签引入外部js文件。我们也可以通过这种方式来实现。

<script src= "https://sp0.baidu.com/5a1Fazu8AA54nxGko9WTAnF6hhy/su?wd=vue&cb=myQueryFuction"></script>

同时我们还需要定义一个与cb参数对应的回调函数,并在函数中执行一系列操作:获取到联想关键词,并将内容挂到页面上展示,并实现点击获取该词条的搜索结果页面。请求响应结果为该函数的实参,因此定义参数的时候要有相对应的形参。

<script>
    var oText = document.getElementById("searchText");

    oText.onkeyup = function(){
        var value = this.value;
        //console.log(value);
        var oScript = document.createElement("script");
        oScript.src= "https://sp0.baidu.com/5a1Fazu8AA54nxGko9WTAnF6hhy/su?wd="+value+"&cb=myQueryFuction";
        document.body.appendChild(oScript);
    }

    var oButton = document.getElementById("button");
    oButton.onclick = function(){
        var val = oText.value;
        console.log(val);
        window.location.assign("https://www.baidu.com/s?wd="+val);
    }

    var keyNode = document.getElementById("keyWords"),
        oUl =  document.getElementById("key");

    function myQueryFuction(data){   //data为对应的形参
        //清除上一次的关键词联想
        oUl.innerHTML = "";
        //console.log(data.s);
        var keywordsArr = data.s;

        //排异处理,使用if判断,当关键词数组长度为0时,关键字联想div隐藏
        if(!keywordsArr.length){
            return keyNode.style.display="none";
        }
        keyNode.style.display="block";
        keywordsArr.forEach(function(val,index){
            var oLi = document.createElement("li");
            oLi.innerText = val;

            oLi.onclick = function(){
                window.location.href = "https://www.baidu.com/s?wd="+val;
            }

            oUl.appendChild(oLi);
        });
    };


</script>

最终,我们搜索vue可以得到以下页面:
这里写图片描述

3 总结

其实这里我们利用的就是JSONP技术。Jsonp(JSON with Padding) 是 json 的一种”使用模式”,可以让网页从别的域名(网站)那获取资料,即跨域读取数据。由于同源策略,一般来说位于 server1.example.com的网页无法与不是 server1.example.com的服务器沟通,而 HTML 的<script>元素是一个例外。利用 <script>元素的这个开放策略,网页可以得到从其他来源动态产生的 JSON 资料,而这种使用模式就是所谓的 JSONP。用 JSONP 抓到的资料并不是 JSON,而是任意的JavaScript,用 JavaScript 直译器执行而不是用 JSON 解析器解析。

JSONP的工作原理是将一个<script>元素动态插入到页面上,并将其源设置为我们要查询的跨域URL。通过在URL的查询字符串上传递相关参数,它可以以表示我们请求的数据的JavaScript格式返回动态响应。

3.1 服务端JSONP格式数据

如客户想访问 : http://www.runoob.com/try/ajax/jsonp.php?jsonp=callbackFunction
假设客户期望返回JSON数据:[“customername1”,”customername2”]。
真正返回到客户端的数据显示为: callbackFunction([“customername1”,”customername2”])。
服务端文件jsonp.php代码为:

<?php
header('Content-type: application/json');
//获取回调函数名
$jsoncallback = htmlspecialchars($_REQUEST ['jsoncallback']);
//json数据
$json_data = '["customername1","customername2"]';
//输出jsonp格式的数据
echo $jsoncallback . "(" . $json_data . ")";
?>

3.2 客户端实现 callbackFunction 函数

<script type="text/javascript">
function callbackFunction(result, methodName)
{
    var html = '<ul>';
    for(var i = 0; i < result.length; i++)
    {
        html += '<li>' + result[i] + '</li>';
    }
    html += '</ul>';
    document.getElementById('divCustomers').innerHTML = html;
}
</script>

页面展示

<div id="divCustomers"></div>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值