纯HTML页面如何使用JSONP解决跨域问题示例

29 篇文章 0 订阅
5 篇文章 0 订阅

你好同学,我是沐爸,欢迎点赞、收藏、评论和关注。

今天不写引言了,我们直接开始。Let’s go.

一、常见问题演示

首先,使用 Express.js 搭建一个简单的服务:

const express = require('express')
const app = express()
const port = 3000

app.get('/data', (req, res) => {
  // 假设这是从数据库或其他服务获取的数据
  const data = { name: 'John Doe', age: 30 }
  res.json(data)
})

app.listen(port, () => {
  console.log(`Server running on port ${port}`)
})

然后写一个纯HTML并请求服务器数据,以xhr-demo.html为例:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>XHR Example</title>
  </head>

  <body>
    <div id="content">hello world</div>
    <script>
      // 创建一个新的XMLHttpRequest对象
      var xhr = new XMLHttpRequest()

      // 配置请求
      xhr.open('GET', 'http://localhost:3000/data', true)

      // 设置请求完成时的回调函数
      xhr.onload = function () {
        // 检查请求是否成功完成
        if (xhr.status >= 200 && xhr.status < 300) {
          // 处理响应
          console.log(xhr.responseText)
        } else {
          // 请求失败
          console.error('Request failed. Returned status of ' + xhr.status)
        }
      }

      // 设置请求失败时的回调函数(可选)
      xhr.onerror = function () {
        // 处理网络错误
        console.error('Network Error')
      }

      // 发送请求
      xhr.send()
    </script>
  </body>
</html>

可以看到,xhr-demo.html 代码中直接请求了服务端接口,明眼人都能看出,这往往会报跨域错误,因为触犯了浏览器的同源策略。

image.png
针对这种跨域问题该怎么解决呢?对于get请求产生的跨域问题,解决跨域的一种方案是使用JSONP。接下来,我们正式看下JSONP是怎么解决跨域的。

二、JSONP解决跨域

JSONP(JSON with Padding)是一种非官方的跨域数据交互协议,它允许在服务器端集成Script标签返回至客户端,通过动态创建<script>标签,并设置其src属性为跨域URL(该URL返回一段JavaScript代码,通常是函数调用,并携带数据作为参数),从而绕过同源策略的限制,实现跨域请求。

以下是一个使用JSONP解决HTML页面跨域问题的示例:

1.服务器端代码(假设使用Node.js和Express)

首先,你需要一个服务器端接口,该接口能够识别JSONP请求,并返回相应的JSONP格式数据。

const express = require('express');  
const app = express();  
const port = 3000;  
  
app.get('/data', (req, res) => {  
    // 假设这是从数据库或其他服务获取的数据  
    const data = { name: 'John Doe', age: 30 };  
  
    // 检查是否有callback参数,这是JSONP的标志  
    const callback = req.query.callback;  
  
    // 构造JSONP响应  
    if (callback) {  
        res.header('Content-Type', 'application/javascript');  
        res.send(`${callback}(${JSON.stringify(data)})`);  
    } else {  
        // 如果不是JSONP请求,可以返回普通JSON或其他  
        res.json(data);  
    }  
});  
  
app.listen(port, () => {  
    console.log(`Server running on port ${port}`);  
});

不知道上述代码如何运行?新建一个文件夹,依次执行npm init -y => npm install express ,新建 index.js文件并拷贝上面的示例代码,接着打开命令行工具,在文件夹所在目录执行 node index.js 即可。

2.客户端HTML页面

然后,在客户端HTML页面中,你可以通过动态创建<script>标签来请求这个JSONP接口。

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>JSONP Example</title>
  </head>

  <body>
    <div id="content">hello world</div>
    <script>
      // 定义一个全局函数,用于处理JSONP响应
      function handleResponse(data) {
        console.log(data) // 假设控制台输出:{ name: 'John Doe', age: 30 }

        // 你可以在这里处理数据,比如更新DOM等
        let content = document.getElementById('content')
        content.innerHTML = '这是来自服务器的数据: ' + JSON.stringify(data)
      }

      // 动态创建script标签,并设置其src属性为JSONP请求的URL,并携带callback参数
      function fetchData() {
        let script = document.createElement('script')
        script.src = 'http://localhost:3000/data?callback=handleResponse'

        // 监听加载完成事件
        script.onload = function () {
          // 加载完成后,从DOM中移除<script>标签
          this.remove()
          // 可以在这里添加其他加载完成后的处理逻辑
          console.log('Data loaded successfully.')
        }

        // 将<script>标签添加到DOM中
        document.body.appendChild(script)
      }

      // 调用函数以开始请求
      setTimeout(function () {
        fetchData()
      }, 2000)
    </script>
  </body>
</html>

在这个例子中,当HTML页面加载时,fetchData函数会被调用,该函数会创建一个<script>标签,并将其src属性设置为指向你的Node.js服务器的/data路由,并附加了一个callback查询参数,其值为handleResponse(这是你在HTML页面中定义的全局函数名)。服务器响应时,会调用这个函数,并将数据作为参数传递给它。

3.效果预览

jsonp-demo.gif

三、总结

JSONP对于解决GET请求的跨域问题还是非常方便的,无论是接口测试还是应对面试,了解JSONP的相应原理和使用对你会很有帮助。

请注意,由于JSONP依赖于<script>标签的跨域能力,它只能发送GET请求,并且存在安全风险(如XSS攻击),因此在现代Web开发中,更推荐使用CORS(跨源资源共享)作为跨域通信的解决方案。

好了,分享结束,谢谢点赞,下期再见。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

沐爸muba

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

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

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

打赏作者

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

抵扣说明:

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

余额充值