js实现跨域的几种方法汇总(图片ping、JSONP和CORS)

概述

跨域是指在同源策略限制下,客户端无法向不同源(协议、域名、端口)的服务器发送请求。但有些情况下需要跨域请求,这时可以使用以下几种方法:图片ping、JSONP和CORS。

方法一:图片ping

通过创建一个HTML的日志资源文件来达到跨域目的,将数据转化为图片地址,然后请求这个图片地址。

<img src="http://example.com/?data=[data]" />

这样发送是不会中止请求的,即使服务器不支持任何的输出形式。

优缺点:
- 优点:对浏览器兼容性要求较低,一般都可以完成跨域操作。
- 缺点:只能使用 GET 请求方式,并且无法设置请求头,只能从服务器拿到请求成功或失败的结果,且不能获得服务端返回的数据。

方法二:JSONP

JSONP 全称为 JSON with Padding,简单来说就是在js里面执行函数,为什么要用padding呢?因为 JSONP其实是利用<script>标签来实现的,可以被普通的浏览器进行跨域访问的特性,这种格式的数据很难实现由 JSON 转译成 JSONP,因此使用了这种 hack 的方式。padding其实是指要在服务端将JSON数据填入到一对用户定义的函数调用中(函数名在URL中),从而构成JS文件(JSONP文件)。

假设客户端需要从 http://example.com/?callback=func 这个URL获取数据,并且要求接口返回的数据格式为 callback(data)

function func(data) {
  console.log(data)
}

const script = document.createElement('script')
script.src = 'http://example.com/?callback=func'
document.head.append(script)

在这个js文件中,会向服务器发送一个 URL 请求,并且 URL 中包含一个名为callback的参数,这个参数的值就是要获得 JSON 数据之后要立即调用的函数名,在服务器端将数据放进其中,并返回这个 js 文件内容,客户端浏览器接收到这个js文件之后,会自动执行func(data)函数。

优缺点:
- 优点:能跨域请求跨域数据,不受同源策略限制,支持 GET 请求,可以向服务端发送请求时设置请求头。
- 缺点:只支持 GET 请求,并且必须判断响应的数据格式,需要服务端配合,且容易受到XSS攻击。

方法三:CORS

CORS 全称为 Cross-Origin Resource Sharing,是 HTML5 提供的一种机制,采用额外的 HTTP 头来告诉浏览器,以允许 Web 应用程序访问不属于其来源的选定资源,浏览器会对复杂请求(例如:get/post以及POST的两种Content-Type:application/json,application/x-www-form-urlencoded)发起一次预检,可以看做是一次请求前置确认,服务器返回“METHOD,Origin,Accept-language,Accept”等字段,携带带校验信息,让浏览器放行实际的请求。

在服务器端,需要添加如下响应头:

Access-Control-Allow-Origin: http://example.com
Access-Control-Allow-Methods: POST,GET,OPTIONS
Access-Control-Max-Age: 1000
Access-Control-Allow-Headers: Content-Type, Authorization

在客户端,直接发送 AJAX 请求,浏览器会自动在请求头中添加Origin字段发起预检请求,如果服务器支持跨域,会返回以上响应头信息。

const xhr = new XMLHttpRequest()
xhr.open('POST', 'http://example.com/api')
xhr.setRequestHeader('Content-Type', 'application/json')
xhr.setRequestHeader('Authorization', 'Bearer ' + token)
xhr.onreadystatechange = function () {
  if (xhr.readyState === 4 && xhr.status === 200) {
    console.log(xhr.responseText)
  }
}
xhr.send(JSON.stringify({data: 'some data'}))

优缺点:
- 优点:绝大多数浏览器都支持,以标准化的请求头、状态码、请求方法来对跨域请求和响应进行规范,同时支持 GET/POST 等请求方式。
- 缺点:需要服务器端进行配置,在某些第三方库中并不支持 CORS。

示例一

通过JSONP方式从服务器获取数据。

服务端随意设置一个接口,返回数据。

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

app.get('/jsonp', (req, res) => {
  const callback = req.query.callback
  const data = {a: 1, b: 2, c: 3}
  res.send(`${callback}(${JSON.stringify(data)})`)
})

app.listen(3000, () => console.log('listening on port 3000'))

客户端通过JSONP跨域获取数据,代码如下所示:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>JSONP Demo</title>
</head>
<body>
  <script>
    function handleData(data) {
      console.log(data)
    }

    const script = document.createElement('script')
    script.src = 'http://localhost:3000/jsonp?callback=handleData'
    document.head.append(script)
  </script>
</body>
</html>

示例二

通过CORS方式从服务器获取数据。

服务端随意设置一个接口,返回数据。

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

app.use((req, res, next) => {
  res.header('Access-Control-Allow-Origin', '*')
  res.header('Access-Control-Allow-Methods', 'GET,POST,OPTIONS')
  res.header('Access-Control-Allow-Headers', 'Origin,Content-Type,Authorization')
  next()
})

app.post('/cors', (req, res) => {
  const data = req.body
  res.json(data)
})

app.listen(3000, () => console.log('listening on port 3000'))

客户端通过 AJAX 跨域获取数据,代码如下所示:

const xhr = new XMLHttpRequest()
xhr.open('POST', 'http://localhost:3000/cors')
xhr.setRequestHeader('Content-Type', 'application/json')
xhr.setRequestHeader('Authorization', 'Bearer ' + token)
xhr.onreadystatechange = function () {
  if (xhr.readyState === 4 && xhr.status === 200) {
    console.log(xhr.responseText)
  }
}
xhr.send(JSON.stringify({data: 'some data'}))

结语

以上三种方法均可用于跨域请求,但不同的请求方式适用于不同的场景,需要根据实际业务情况选择。而若是自身网站项目,建议使用第三种CORS方式,若要集成第三方传输库则可考虑JSONP方式。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:js实现跨域的几种方法汇总(图片ping、JSONP和CORS) - Python技术站

(0)
上一篇 2023年5月17日
下一篇 2023年5月17日

相关文章

  • Linux云计算工程师

    一、Linux运维基础 二、Linux运维高级-核心知识提高 三、50台集群实战 四、200-1000台集群实战 五、shell编程企业级实战 六、数据库MySQL和NoSQL 七、LVM虚拟化和机房知识

    云计算 2023年4月13日
    00
  • 云计算网络 ASW DSW CSW LSW

    ASW (接入层交换机)数据交换模块接入交换机,接入云服务器,上行互联核心交换机DSW。DSW (分布层交换机):核心交换机,用于连接各个ASW接入交换机。CSW (内网接入交换机):接入用户内网骨干,实现云网络内外部的路由分发交互,包括VPC专线接入。CSW可以实现专线侧到XGW的VxLAN封装。LSW (综合接入交换机)综合接入模块,云产品服务接入交换机…

    2023年4月10日
    00
  • 浅谈:Hadoop、spark、SaaS、PaaS、IaaS、云计算

    Hadoop & Spark首先二者均不是属于产品类别,理解为生态系统或者也有人将其称为“大数据通用处理平台”也是可以的,这种称呼也更为准确Hadoop是由Apache基金会所开发的分布式系统基础架构Hadoop主要包括:Hadoop分布式文件系统:一个分布式的、面向块的、不可更新的、高度伸缩性的、可运行在集群中普通硬盘上的文件系统MapReduce…

    云计算 2023年4月13日
    00
  • 阿里云数据库李飞飞:云计算推动数据库向云原生快速演进

    12月30日,阿里云云原生数据库PolarDB举行年度发布。过去的一年是阿里云数据库硕果累累的一年。11月,Gartner公布阿里云进入全球数据库领导者象限,是国产数据库几十年积累的重大突破;12月,中国电子学会公布PolarDB获得科学技术奖一等奖。阿里云数据库深耕11年,至今已服务客户10万余。 阿里巴巴集团副总裁、阿里云智能数据库事业部总裁李飞飞表示,…

    2023年4月9日
    00
  • Linux云计算架构-Zabbix变量和模板使用

    文章目录 Linux云计算架构-Zabbix变量和模板使用 1. 为什么需要模板? 2. 设置变量 3. 创建含有变量的面板 Linux云计算架构-Zabbix变量和模板使用 1. 为什么需要模板? 原因如下:正常情况下,当配置某个面板时,需要设置群组和主机名,否则无法获取到对应主机的数据。假如有10台主机需要监控,就得重复配置10次。若有10个监控指标,就…

    云计算 2023年4月12日
    00
  • 云计算助力生命科学探索

    “人类DNA序列是人类的真谛,这个世界上发生的一切事情,都与这一序列息息相关。” ——诺贝尔生理学与医学奖获得者杜伯克     在基因这本“生命天书”里,藏着有关健康的秘密,人类通过基因探索生命科学的脚步从未停歇。然而,对生命科学的探究离不开对基因数据信息的存储、挖掘、管理。其数据信息的巨大规模、结构复杂、快速增长等特点,对信息系统的存储能力、计算能力、扩展…

    云计算 2023年4月12日
    00
  • Python中urllib+urllib2+cookielib模块编写爬虫实战

    一、Python中urllib+urllib2+cookielib模块编写爬虫实战攻略 最常用的Python爬虫模块之一就是urllib库和urllib2库,它们可以用于进行HTTP(S)请求,获取网页源代码等操作。同时我们还可以使用Python中的cookielib模块来管理Cookies,模拟登录,配合urllib+urllib2使用可以实现爬虫的功能。…

    云计算 2023年5月18日
    00
  • 这只猫在云端定居了?边缘计算在天猫精灵云应用上的落地实践

    IoT的概念早已飞入寻常百姓家,在你我的日常生活中发挥着“智能”作用。比如,智能家居、智慧照明、GPS 导航、手机计步器等。未来,随着用户和技术的延伸和拓展,物联网的信息交换和通信价值将会被继续放大。 那么问题来了,如此庞大的设备和信息量,如何进行管理和整合重组?如何高效准确智能地对用户需求和实际应用场景做出反应?如何让数据流动产生更大价值? 如何向着更智慧…

    云计算 2023年4月17日
    00
合作推广
合作推广
分享本页
返回顶部