Ajax&jsonp初步

Ajax&jsonp初步

Ajax初步

Ajax(Asynchronous JavaScript and XML)是一种使用多种技术的组合,创建快速动态网页应用的开发技术。Ajax 不是一种新的编程语言,而是一种使用现有标准的新方法。它利用 JavaScript 在浏览器与服务器之间异步地交换数据,使网页应用能够更快地更新和响应。

Ajax 的主要特点包括:

  • 异步性:Ajax 使用异步方式与服务器通信,这意味着浏览器不会在等待服务器响应时阻塞用户界面。这使得网页能够继续响应用户的其他操作,而无需重新加载整个页面。
  • 局部更新:通过 Ajax,只有页面的特定部分需要更新,而不是整个页面。这提供了更好的用户体验,因为用户不需要等待整个页面重新加载。
  • 无刷新:使用 Ajax 的网页应用通常不会刷新或跳转页面,而是动态地更新内容。
  • 跨平台性:Ajax 基于 Web 标准,因此可以在大多数现代浏览器中运行,无论操作系统如何。

Ajax 的基本工作原理如下:

  • 创建XMLHttpRequest对象:这是 Ajax 通信的核心。它允许 JavaScript 与服务器建立连接并发送请求。
  • 发送请求:使用 XMLHttpRequest 对象的 open() 方法设置请求类型(GET、POST 等)和 URL,然后使用 send() 方法发送请求。
  • 处理响应:通过监听 XMLHttpRequest 对象的 onreadystatechange 事件,可以检测服务器的响应状态。一旦响应准备好,可以读取服务器的响应数据(通常是 XML 或 JSON 格式)。
  • 更新页面:使用 JavaScript 解析和处理从服务器接收的数据,并动态地更新页面的相应部分。

尽管 Ajax 提供了许多优势,但它也有一些缺点和考虑因素,如安全性问题、跨域限制(CORS)、浏览器兼容性等。


下面我们通过编写JavaScript代码来实现Ajax请求:

准备:

  • 在本地先创建一个json文件,以便通过Ajax请求获取
  • 在本地开启一个服务,可以通过node的npm命令安装serve:npm install serve,随后执行serve即可:

在这里插入图片描述

我当前已经将js文件和json文件存放在一个路径,下面是html页面(index.html):

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Ajax get user data</title>
    </head>
    <body>
        <script type="text/javascript" src="./js/js.js"></script>
    </body>
</html>

json数据(userdata.json):

{
    "username":"tom",
    "userage":18
}

通过JavaScript实现Ajax请求的代码(js.js):

var xhr = new XMLHttpRequest(); // 创建XMLHttpRequest对象

request_url = 'http://localhost:3000/js/userdata.json';

xhr.open('GET',request_url,true) //设置请求方法和URL,并且开启异步执行

//监听请求状态的变化
xhr.onreadystatechange = function(){
    if(xhr.readyState == 4 && xhr.status == 200){ // 当请求完成,并且响应状态码为200正常时
        var responseData = JSON.parse(xhr.responseText);
		console.log(responseData)
        console.log(responseData.username);
        console.log(responseData.userage);
    }
}

xhr.send() //发送请求

首先是创建了一个新的XMLHttpRequest对象实例,用于发起HTTP请求。

随后定义了一个变量request_url,并设置其值为请求的URL。这个URL指向本地服务器上的一个JSON文件。

xhr.open('GET',request_url,true);:这行代码配置了XMLHttpRequest对象:

  • ‘GET’:请求方法设置为GET,意味着我们想要从服务器获取数据。
  • request_url:请求的URL。
  • true:表示这是一个异步请求,即JavaScript不会等待响应就继续执行后续代码。

再者定义了一个事件监听器,用于监听XMLHttpRequest对象的readystatechange事件。当请求的状态发生变化时,这个事件就会被触发。

if(xhr.readyState == 4 && xhr.status == 200){ ... },在事件监听器函数内部,这个if语句检查两个条件:

  • xhr.readyState == 4:确保请求已完成(readyState为4表示请求已完成)。
  • xhr.status == 200:确保服务器的响应状态码是200,表示请求成功。

如果上述条件满足,就将响应的文本(xhr.responseText)解析为JavaScript对象,并存储在responseData变量中,并将对象的属性值打印到控制台。

xhr.send();:这行代码发送HTTP请求到指定的URL。

进入http://localhost:3000/打开控制台即可看到效果:

在这里插入图片描述

除了发送get请求,我们还可以发送post请求,实现起来的代码其实和get差不多(假如我们要提交json数据):

  • 通过JSON.stringify({ key: 'value' })来将对象转换为JSON字符串
  • 通过xhr.setRequestHeader();来设置请求头
  • 最后发送请求即可

当然,我们还可以通过引入jQuery来实现Ajax请求:

  • 我们需要再html文档中插入:<script src="js/jquery-1.12.4.min.js"></script>来引入jQuery

随后改写js代码:

$.ajax({
    url:'js/userdata.json', //请求地址
    type:'get', //请求类型
    dataType:'json', //请求数据类型
    success:function(data){ // 成功时
		console.log(responseData)
        console.log(data.username);
        console.log(data.userage)
    },
    error:function(){ // 失败时
        console.error('Ajax请求失败!')
    } 
})

在上面的代码中我们通过$.ajax()方法来发起一个异步HTTP GET请求。

  • $.ajax()是jQuery中用于处理AJAX(Asynchronous JavaScript and XML)请求的一个非常强大的函数。

随后它接受一个包含请求配置的对象作为参数,这里设置的参数是:

  • 请求的URL
  • 请求的类型
  • 以及告诉jQuery期望服务器返回的数据类型

随后又定义了一个请求成功时回调函数,和请求失败时回调的函数

上述的jQuery代码我们是比较传统的Ajax请求代码,目前为止我们还可以使用以下代码来实现:

$.ajax({
    url:'js/userdata.json',
    type:'get',
    dataType:'json',
})
.done(function(data){
    console.log(data)
    console.log(data.username);
    console.log(data.userage);
})
.fail(function(){
    console.error('Ajax请求失败!')
})

在这种写法中,我们使用了链式调用的方式。$.ajax()方法返回了一个jqXHR对象,该对象具有.done()和.fail()等方法,用于分别注册成功和失败的回调函数。这种写法通常被认为更具可读性,尤其是当你有多个回调函数需要链式处理时。

两者的主要区别在于:

  • 第一种写法直接在$.ajax()方法中定义回调,代码更紧凑,但可能对于更复杂的逻辑或更多的回调函数来说不太易于管理。
  • 第二种写法使用链式调用,代码更加模块化,易于扩展和阅读,尤其是当处理多个步骤或异步操作时。

Jsonp

在Ajax请求的介绍中,我们提到它不能跨域限制的缺点,也就是说Ajax不能跨域请求。即当我们要在x.com这个域下请求y.com的数据的时候是不行的。那么这个时候我们引入了Jsonp

JSONP(JSON with Padding)和Ajax(Asynchronous Javascript And XML)都是用于Web开发的技术,但它们的目的和工作方式有所不同。

JSONP是JSON的一种“使用模式”,主要用于解决主流浏览器的跨域数据访问问题。由于同源策略的限制,一个网页通常无法与不同源的服务器进行通信,但HTML的<script>元素是一个例外,在<script>所指定的src属性中是可以进行跨域请求操作的。JSONP利用这个特性,通过动态添加<script>标签来调用服务器提供的JS脚本,从而获取跨域的数据。

实现的原理就是:

  • JSONP允许用户传递一个callback参数给服务端,服务端返回数据时,会将这个callback参数作为函数名来包裹住JSON数据。这样,客户端就可以定义自己的函数来自动处理返回的数据。

在jQuery中,jsonp被封装在了$.ajax()中。值得注意的是,jsonp只能进行get请求,不能进行post请求。

下面展示在jQuery中如何使用jsonp来请求数据:

$.ajax({
    url:'js/js.js', 
    type:'get',
    dataType:'jsonp',
    jsonpCallback:'back', 
})
.done(function(data){
    console.log(data.username);
	console.log(data.age);
})
.fail(function(){
    console.error('Jsonp请求失败!');
})

可以看到,大致的代码的Ajax请求时的代码一样,不同的就是url后面请求的文件为.js,数据类型为jsonp,并且还有一个jsonpCallback

JSONP的核心在于动态添加<script>标签,url 应该指向一个服务器端脚本,这个脚本负责生成并返回JSONP格式的响应。这个服务器端脚本可以用任何后端语言编写,包括但不限于Java、Python、PHP、Node.js等。

当浏览器加载这个<script>标签时,它会执行返回的JavaScript代码,即调用在jsonpCallback中指定的回调函数back并传入数据对象。

随后我们就可以在请求成功后的回调函数中,传入从服务器接收到的数据并显示。

这个用户返回json数据的js脚本可以这么写:

back({'username':'tom','age':18});

下面我们在通过原生JavaScript代码实现Jsonp请求的效果:

function jsonp(url,callback){
    var newScript = document.createElement('script');
    var callBackName = 'back'; // 申明回调函数名

    window[callBackName] = function(data){
        document.body.removeChild(newScript);
        callback(data);
        window[callBackName] = null //清理全局回调函数
    }

    url += (url.indexOf('?')>0 ? '&' : '?')+'callback='+callBackName //合成url
    newScript.src = url;

    document.body.appendChild(newScript) 
}

jsonp("http://localhost:3000/js/json.js",function(data){
    console.log(data);
})

先来解释一下这里的js代码:

  • 我们首先创建了一个jsonp函数,用来实现jsonp请求的作用,该函数接受两个参数:请求url、回显数据函数

  • 在函数内部我们,创建了script标签以及json脚本返回json数据的回调函数名

  • 随后将该函数名作为全局函数,并创建

  • 随后对url进行格式合成,具体就是判断该url后面的有?和没有?时添加的内容

  • 最后将url添加到新创建的script中后将script载入页面执行

-当script标签引入url加载之后,返回值给到全局函数 window[callBackName],从而触发全局函数执行,执行后删除添加的script标签,并调用显示接受到数据的函数,传入script返回给全局函数的数据,(该数据最先是通过全局函数的data接收的),之后清理本身避免内存泄露

在body中引入脚本,实现效果:

在这里插入图片描述


下面我们来做一个Jsonp请求的效果,使用jQuery用Jsonp请求通过使用360搜索引擎公用API获取json数据实现仿360搜索的功能

首先,来到so.com网页:

在这里插入图片描述

通过检查->网络进行对json数据产生的脚本获取:

  • 首先清空内容,然后在输入框中任意输入数据

在这里插入图片描述

从加载的数据文件中可以看到对应的script类型的文件,通过预览可以看到其数据:

在这里插入图片描述

这个脚本中的json数据回调函数为suggest_so()

复制其脚本链接,在页面内显示为如图:

在这里插入图片描述

在这里插入图片描述

这时我们可以编写对应的jsonp请求来进行跨域请求数据

html页面如下(index.html):

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>360搜索联想词</title>
    </head>
    <script src="./jquery-1.12.4.min.js"></script>
    <script type="text/javascript" src="./js-jsonp.js"></script>
    <body>
        <h1>基于360API搜索引擎</h1>
        <div class="sousuo">
            <label>搜索:</label><input id="input-sousuo" type="text">
            <ul class="list-li">
            </ul>
        </div>
    </body>
</html>

JavaScript引入jQuery来实现jsonp请求如下(js-jsonp.js):

$(function(){
    $('#input-sousuo').keyup(function(){
        var input_text = $(this).val(); //获取输入的搜索内容
        $('.list-li').empty() //动态更新搜索内容
        $.ajax({
            url:"https://sug.so.360.cn/suggest",
            type:'get',
            dataType:'jsonp',
            jsonpCallback:'suggest_so',
            data:{"word":input_text}
        })
        .done(function(data){
            lainxiangci_arry = data.result; //获取json
            console.log(lainxiangci_arry);
            for(var i =0;i<lainxiangci_arry.length;i++){
                li = $('<li>');
                content_a = $('<a>');
                content_a.attr('href','https://www.so.com/s?q='+lainxiangci_arry[i].word);
                content_a.html(lainxiangci_arry[i].word);
                li.html(content_a); // 向列表插入内容指向的链接
                li.appendTo($('.list-li'));
            }
        })
        .fail(function(){
            console.error("Jsonp请求失败!");
        })
    })
})
  • 通过监听input输入框中值的变化删除li标签,实现动态更新搜索内容
  • 请求的url为:https://sug.so.360.cn/suggest
  • 通过for循环来遍历提取数据即可
  • 在向页面插入数据时我们指定的<a>标签中的链接为360搜索指定内容时的跳转链接,这个我们可以通过观察在搜索指定内容时获取其url:

在这里插入图片描述

最后我们可以实现的效果如下所示:

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

moment&forever

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值