jsonp跨域详解+模拟百度搜索(代码片段)

bear*6 bear*6     2023-02-22     725

关键词:

一、什么是JSONP

        JSONP是JSON with padding(填充式JSON或参数式JSON)的简写,是应用JSON的一种新方法,在后来的Web服务中非常流行,JSONP看起来与JSON差不多,只不过是被包含在函数中调用的JSON,就像下面这样:

callback("name": "王欢");

        JSONP由两部分组成:回调函数和数据。回调函数是当响应到来时应该在页面 中调用的函数。回调函数的名字一般是在请求中指定的。而数据就是传入回调函数中的JSON数据。下面就是一个典型的JSONP请求。

https://freegeoip.net/json/?callback=handleResponse

        这个URL是在请求一个JSONP地理定位服务,通过查询字符串来指定JSONP服务的回调参数是很常见的,就像上面的URL所示,这里指定的回调函数的名字叫做:handleResponse()
        JSONP是通过动态<script>元素来使用的,使用时可以为src属性指定一个跨域URL。可以不受限制的从其他域加载资源,因为JSONP是有效的JavaScript代码,所以在请求完成后,即在JSONP响应加载到页面中以后,就会立即执行。

二、JSONP跨域请求

        我们知道,同源策略是浏览器的一种安全机制,所谓的源是指协议、域名和端口号,当我们的脚本在运行时,浏览器会检测它所执行的脚本和他所取得的的数据与我们HTML页面是否相同,如果相同,就是同源的,会进行成功的请求,如果他们的源不相同,就是跨域请求。在默认情况下,浏览器是不支持跨域请求的,那么如果我们想要跨域请求,该如何操作呢?
        script标签是不受同源策略的限制的,即我们在请求script脚本的时候,无论是在HTML所在的服务器还是其他服务器,它都可以请求到,所以我们就利用script标签的这种性质来进行数据的跨域请求。就来看看JSONP是如何进行跨域请求的。
        首先,我们请求一段script代码,这段代码里如果它能调用我们所指定的一个函数,并将数据作为实参传递进来,那么只要我们定义了这个函数并定义了形参,形参就会接收到他的实参来得到数据。举个例子:
        假设在脚本中定义了一个getData(data),如果现在请求一个脚本,这个脚本能够调用getData()这个函数,并将data 作为实参传递进来,那形参收到的数据就可以进行相应的处理。

<script>
        function getData(data)
            console.log(data);
        
        var script = document.createElement('script');
        script.id = 'jsonp';
        script.src = 'jsonp.js';
        document.body.appendChild(script);
    </script>

        假设前端已经把函数名告诉了后端,后端就可以调用这个getData(),并且可以传递信息。在jsonp.html就可以请求到下述jsonp.js文件。

getData(
    name: '小王',
    age: 20
)

        运行得到结果为:

        得到了一个Object对象,就是我们所传递的数据。
        那么,我们如何告诉服务器getData()这个函数呢?如果我们每次都固定是getData(),我们的开发会很死板,就不能定义其他函数名字。实际上,我们可以通过get请求将我们前端定义的函数名字通过参数告诉后端,后端动态生成这样的一个脚本文件并返回给函数的调用就可以。
        百度就有一个这样的接口,我们一起来看看。
        打开浏览器百度页面,打开调试工具,看一下NETwork标签下面会监听所有关于浏览器向服务器发送的http请求并查看数据。
        在搜索框键入“b”,请求如图:

        请求得到的关键字为:

        这里的callback函数其实是jquery生成的一个全局函数。得到这个URL后,我们可以保存其有用的信息,并将回调函数换成别的函数:

https://www.baidu.com/sugrec?pre=1&wd=b&req=2&csor=1&cb=getData();

        将其输入到地址栏中进行测试:

        可以发现,这个回调函数就变成了我们设置的。

三、模拟百度搜索

        我们现在就可以通过这个接口去发生JSON来模拟一下百度搜索页面。
代码如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        div 
            position: relative;
            width: 600px;
            height: 40px;
        
        input 
            width: 500px;
            height: 40px;
            border: 2px solid #4E6EF2;
        
        button
            position: absolute;
            left: 411px;
            top: 0;
            width: 95px;
            height: 44px;
            background-color: #4E6EF2;
            border: none;
            font-size: 18px;
            color: white;
        
        ul
            position: relative;
            left: -40px;
            top: -10px;
            width: 411px;
            height: 400px;
            
        
        li
            height: 40px;
            width: 411px;
            line-height: 40px;
            font-size: 16px;
            list-style: none;

        
    </style>
</head>
<body>
   <div>
    <input type="text" value =''>
    <button>百度一下</button>
   </div>
    <ul></ul>
    <script src="jquery.js"></script>
    <script>
        function getData(data)
            var script = document.querySelector('#jsonp');
            script.parentNode.removeChild(script);
            $('ul').html('');
            for(var i =0;i<data.g.length;i++)
                $('<li>'+data.g[i].q +'</li>').appendTo('ul');
            
        
        function getList(wd)
            var script = document.createElement('script');
            script.id = 'jsonp';
            script.src = 'https://www.baidu.com/sugrec?pre=1&p=3&ie=utf-8&json=1&prod=pc&from=pc_web&sugsid=26350&req=2&csor=1&cb=getData&wd='+wd;
           
            document.body.appendChild(script);
        

        var ipt = document.querySelector('input');
        ipt.addEventListener('keyup',function()
            var wd = this.value;
            getList(wd);
            console.log(wd);
        )
    </script>
</body>
</html>

效果为:

四、JSONP缺点

        JSONP之所以在开发人员中极为流行,是因为它非常简单易用,不过他也有两点不足:

  • 首先,JSONP是从其他域中加载执行代码。如果其他域不安全,很可能会在响应中夹带一些恶意代码,而此时除了完全放弃JSONP调用之外,没有办法追究。
  • 其次,要确定JSONP请求是否失败并不容易。虽然HTML5给<script>元素新增了一个onerror事件处理程序,但目前还没有得到任何浏览器的支持。为此,开发人员不得不使用计时器检测指定时间内是否接收到了响应。但是毕竟不是每个用户的上网速度和带宽都一样,所以操作起来也不尽人意。

jsonp跨域实例丨利用百度数据制作搜索页面

<!DOCTYPEhtml><html>   <head>       <metacharset="UTF-8">       <title>Title</titl 查看详情

百度下拉智能搜索提示(代码片段)

...案例使用的时ajax技术实现百度下拉,其中有利用jsonp解决跨域的问题,目前刚接触到ajax技术,在这里分享记录一下学习的痕迹!<!doctypehtml><htmllang="en"><head><metacharset="UTF-8"><title>EMS-jquery查询</title><styl... 查看详情

跨域问题详解(代码片段)

浅谈跨域阅读须知:作者是一个在校大学生,尚未工作,以下内容依据个人理解与网上资料编写。若有错误,还请指出,感激不尽。网上对于跨域的解释大多是一堆文字,对于初学者来说往往较难理解,这篇博客我将利用NodeJs搭建一... 查看详情

详解cors跨域的几种不同实现方式(代码片段)

CORS定义CORS是一个W3C标准,全称是"跨域资源共享"(Cross-originresourcesharing),它允许浏览器向跨源服务器,发出XMLHttpRequest请求,从而克服了AJAX只能同源使用的限制。提供了Web服务从不同域传来沙盒脚本的方法,以避开浏览器的... 查看详情

解决跨域问题,实例调用百度地图(代码片段)

1.什么是跨域?浏览器对于javascript的同源策略的限制,例如a.com下面的js不能调用b.com中的js,对象或数据(因为a.com和b.com是不同域),所以跨域就出现了。同域的概念又是什么呢?所谓的同源是指,域名、协议、端口均为相同。2.如何解... 查看详情

跨域问题详解(代码片段)

一、跨域原理 1.为什么会产生跨域问题          之所以会产生跨域问题是由于浏览器实现了同源策略(Sameoriginpolicy),同源策略规定发起ajax请求时当原地址(原始域)和请求地址(请求域)的... 查看详情

模拟百度

 今天来写下类似于百度搜索的一个东西,获取百度接口,利用jsonp获取百度数据,实现百度框搜索的功能! 我是用jq来些的 ,我们先引入jq。 <scriptsrc="jquery.min.js>还有我们封装的一个jsonp的一个js 这只是个... 查看详情

jsonp详解

...  1、一个众所周知的问题,Ajax直接请求普通文件存在跨域无权限访问的问题,甭管你是静态页面、动态网页、web服务、WCF,只要是跨域请求,一律不准;  2、不过我们又发现,Web页面上调用js文件时则不受是否跨域的影响... 查看详情

解决跨域问题,实例调用百度地图(代码片段)

1.什么是跨域?浏览器对于javascript的同源策略的限制,例如a.com下面的js不能调用b.com中的js,对象或数据(因为a.com和b.com是不同域),所以跨域就出现了。同域的概念又是什么呢?所谓的同源是指,域名、协议、端口均为相同。前端常见... 查看详情

ajax解决跨域--jsonp原理(代码片段)

1.解决跨域–JSONP1.1JSONP是什么JSONP(JSONwithPadding),是一个非官方的跨域解决方案,纯粹凭借程序员的聪明才智开发出来,只支持get请求。1.2JSONP怎么工作的?在网页有一些标签天生具有跨域能力,比如:imglin... 查看详情

ajax基础4--什么是跨域以及如何解决跨域(代码片段)

...策略和jsonp同源策略(⭐⭐⭐)什么是同源什么是同源策略跨域(⭐⭐⭐)什么是跨域浏览器对跨域请求的拦截如何实现跨域数据请求`JSONP`什么是`JSONP`(⭐⭐⭐)`JSONP`的实现原理(⭐⭐⭐)自己实现一个简单的`JSONP`... 查看详情

jsonp原理详解

...生的:一个众所周知的问题,Ajax直接请求普通文件存在跨域无权限访问的问题,甭管你是静态页面、动态网页、web服务、WCF,只要是跨域请求,一律不准。不过我们又发现,Web页面上调用js文件时则不受是否跨域的影响(不仅如... 查看详情

android中实现模拟搜索的功能详解(代码片段)

先看效果图,合适了再接着往下看:我们看到的这个页面,是由两部分组成,顶部的自定义的搜索框,和listView组成。首先我们来实现布局页面,自定义搜索框,和设置listView<?xmlversion="1.0"enc... 查看详情

前端面试--ajax和jsonp跨域(代码片段)

<!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"><metahttp-equiv="X-UA-Compatible"content="IE=edge"><metanam 查看详情

python爬取百度搜索页面,得到内容不全,求教,why

...通用的逻辑和原理;2、以提取songtaste网页中标题为例,详解如何抓取网站并提取网页内容;3、以模拟登陆百度为例,详解如何模拟登陆网站;4、以抓取网易博客帖子中的最近读者信息为例,详解如何抓取动态网页中... 参考技... 查看详情

处理跨域的方法(代码片段)

处理跨域有4中方法分别是:JSONP、CORS、WebSocket、PostMessage一·首先介绍一下JSONP原理    JSONP是利用<script>标签的开放策略,网页可以得到从其他来源动态产生的json数据,JSONP请求一定需要对法国的服务器做支... 查看详情

ajax解决跨域--jquery发送jsonp请求(代码片段)

1.jQuery发送jsonp请求需求在"点击发送jsonp请求"后,将服务器返回的响应体渲染到窗口中。ajaxDemo.html<!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"><metaname= 查看详情

cors和jsonp的区别,如何解决跨域问题?(代码片段)

...用cors和jsonp呢?实际上,cors和jsonp都是用于解决跨域问题,当两个页面的协议、域名、端口号中有一个不一致时就存在了跨域,一旦出现跨域,浏览器发送跨域请求后,请求回来的数据都会被浏览器所拦截... 查看详情