当前位置: 首页 > article >正文

Ajax:跨域 JSONP

Ajax:跨域 & JSONP

    • 同源与跨域
      • 同源
      • 跨域
    • JSONP
      • jQuery发送JSONP


同源与跨域

同源

如果两个页面的协议、域名、端口号都相同,则两个页面同源

例如:

http://www.test.com/index.html

与其同源的网页:

http://www.test.com/other.html
http://www.test.com:80/other.html

注意,如果一个网址没有写:端口号,说明默认端口号为80

不同源的网页:

http://blog.test.com/other.html      // 域名不同
http://www.test.com:8888/other.html  // 端口不同
https://www.test.com/other.html      // 协议不同

注意,httphttps不是一个协议。

同源策略是浏览器提供的一个安全功能,同源策略限制了从同一个源加载的文档或脚本与另一个源的资源交互,这样可以隔离潜在的恶意文件。

JavaScript就是一种脚本,受到同源策略限制,简单来说就是A网站的JavaScript无法与B网站进行交互。

  1. 无法读取非同源页面的cookielocalStorage
  2. 无法接触非同源页面的DOM
  3. 无法向非同源地址发送Ajax请求

跨域

如果两个页面的协议、域名、端口号有任何一项不同,则两个页面跨域

也就是说,同源的对立面就是跨域。

基于同源策略,浏览器会对跨域请求进行拦截,如下图:

在这里插入图片描述

浏览器允许用户通过Ajax向跨域的地址发起请求,但是当响应到达浏览器,基于同源策略检测到响应跨域了,那么就会进行拦截,Ajax收不到响应。

为了实现跨域请求,有JSONPCORS两种解决方案。

  • JSONP:兼容性好,兼容低版本IE,只支持GET请求,不支持POST
  • CORS:是跨域请求的根本解决方案,支持GETPOST请求,但是不兼容低版本浏览器

JSONP

JSONP全称Json with Padding,是一种json的使用模式,可以解决主流浏览器的跨域问题。

由于浏览器同源策略的限制,网页中无法通过阿贾克斯请求非同源的接口数据。但是<script>标签不受浏览器同源策略的影响,可以通过src属性,请求非同源的js脚本。

JSONP 的实现原理,就是通过 <script>标签的 src属性,请求跨域的数据接口,并通过函数调用的形式接收跨域接口响应回来的数据。

<script>
  function test(data) {
    console.log(data)
  }
</script>

<script>
  test({ name: '张三', age: 20 })
</script>

以上代码中,定义了两个<script>标签,第一个标签内部实现了test方法,第二个标签内调用了这个方法。由于所有的 <script> 标签共享全局作用域,这是合法的。

假设现在把这个调用的方法放到另一个js文件中./js/test.js

test({ name: 'ls', age: 30 })

./js/test.js文件中,直接调用test方法。

这样可以通过<script src=''>进行引入:

<script>
	function test(data) {
	   console.log(data)
	 }
</script>

<script src="./js/test.js"></script>

这样,当前页面的test方法,就可以被./js/test.js这个文件进行调用。

基于这个策略,可以实现两个服务器之间的JavaScript脚本互相配合,如果想要告诉调用方法的服务器,自己有哪些函数可以调用,可以通过?callback=的方式传递参数:

<script src="./js/test.js?callback=test"></script>

这就是JSONP解决跨域的原理。

测试:

$.ajax({
  method: 'GET',
  url: 'file://D:\code_web\blog\test\test.js',
  success: function (res) {
    console.log(res)
  }
})  

以上代码在test.html中,向file://D:\code_web\blog\test\test.js发起请求,这是一个本地文件路径。为了用户安全考虑,浏览器不允许Ajax直接访问用户主机上的内容,这是基于同源策略实现的。

报错:

在这里插入图片描述

其中Cross origin requests表示这是一个跨域请求。

<script>
  function test(data) {
    console.log(data)
  }
</script>

<script src="file://D:\code_web\blog\test\test.js?callback=test"></script>

同样的情况,把test函数定义在test.html中,通过src=属性选择同一主机下的test.js文件。

在这里插入图片描述

这次请求成功了,可以看到其发送了一个GET请求,去请求file://D:\code_web\blog\test\test.js这个文件,请求成功后,下方的控制台调用函数,并输出调用结果。

要注意的是,平常要通过<script>引入本地js文件,直接src="路径"就可以了,无需file://这样的协议前缀,这里只是为了测试跨域问题。

可以看出<script>可以实现跨域请求,这也是JSONP实现跨域的方式。


jQuery发送JSONP

使用jQuery发送JSONP请求非常简单,增加一个dataType属性即可:

$(function () {
  $.ajax({
    url: 'https://jsonplaceholder.typicode.com/posts?id=1',
    dataType: 'jsonp',
    success: function (res) {
      console.log(res)
    }
  })
})

如果要发送JSONP请求,填入dataType: 'jsonp',由于JSONP只能使用get,所以也不再需要指定请求的方法为get

在这里插入图片描述

发送出去的请求,多出来一个callback=jQuery....参数。这是由jQuery自动生成的,如果通过jQuery发送JSONP请求,其会携带一个callback=jQuery....参数,jQuery....是随机生成的回调函数名称。

jQuery允许用户自己指定这个回调函数的参数:

$.ajax({
  url: 'https://jsonplaceholder.typicode.com/posts?id=1',
  dataType: 'jsonp',
  jsonp: 'call',
  jsonpCallback: 'test',
  success: function (res) {
    console.log(res)
  }
})
  • jsonp:指定回调函数的key
  • jsonpCallback:指定回调函数的value

在这里插入图片描述

此时回调函数就变成了call=test,这可以方便后端进行解析。但是一般不会去指定jsonp,直接用默认的callback即可,更多时候只指定回调函数的函数名。

jQuery也是通过<script>标签的src属性实现的跨域访问,但是jQuery会动态创建和移除<script>标签。在发起请求时创建一个<script>,在请求成功后,再移除刚才创建的标签。



http://www.kler.cn/a/373156.html

相关文章:

  • AI-基本概念-多层感知器模型/CNN/RNN/自注意力模型
  • Vue生成名片二维码带logo并支持下载
  • dedecms手机搜索不跳转手机页面模板的解决方法
  • 如何在小红书发布笔记时显示外地IP地址
  • SASS转换成CSS步骤
  • GitLab代码仓管理安装配置使用
  • 面向对象的需求分析方法
  • etcd多实例配置
  • 开源的GPT-4o模型使用指南,Mini-Omni2集视觉、语音和双工能力于一体的
  • conda激活环境失败
  • 蓝牙资讯|苹果AirPods Pro 2推出听力测试、助听器和听力保护等功能
  • spring boot 3.x 整合Swagger3
  • pcie5.0接口的主板--战未来
  • 爬虫+数据保存2
  • Caffeine 本地缓存测试频繁 GC 场景及部分源码分析
  • Tomcat UrlRewriteFilter 部署项目虚拟路径配置,路由重写,可参考配置部署前端控制路由项目(Vue,React 等)
  • 【华为HCIP实战课程二十四】中间到中间系统协议IS-IS配置实战,网络工程师
  • ChatGPT、Python和OpenCV支持下的空天地遥感数据识别与计算——从0基础到15个案例实战应用
  • 机器学习中的嵌入是什么?
  • 计算机毕业设计PySpark+大模型高考推荐系统 高考分数线预测 高考爬虫 协同过滤推荐算法 Vue.js Django Hadoop 大数据毕设
  • Leetcode—3216. 交换后字典序最小的字符串【简单】
  • 从零到一构建C语言解释器-CPC源码
  • P2link 远程桌面服务的主要用途
  • 安娜的档案(Anna’s Archive) 镜像网站/国内最新可访问入口(持续更新)
  • 【C++进阶】C++11(中)
  • AbstractQueuedSynchronizer