jsonp解决跨域问题

JSONP解决跨域问题

  • 1. 原理分析
    • 1.1 同源策略
    • 1.2 跨域的情形
    • 1.3 跨域问题的解决方案
    • 1.4 什么是JSONP
  • 2. JSONP方案具体实现
    • 2.1动态创建script标签
    • 2.2 用jQuery中$.getJSON()实现JSONP
    • 2.3 用jQuery中$.ajax()实现JSONP
    • 2.4 总结:

最近在学习ajax跨域的问题,为了加深理解,写篇博客记录一下。

1. 原理分析

1.1 同源策略

我们先来看看跨域问题涉及的一些概念:

  • 源: 指页面中数据的来源,由三部分指定:协议名、域名或IP地址、端口号
  • 同源策略:不同源的客户端js脚本在没有明确授权的情况下,不能读写对方资源(a.com下的js脚本采用ajax不能读取b.com里面的文件数据,会发生跨域错误)
  • 跨域错误:(如下图)
    在这里插入图片描述

1.2 跨域的情形

jsonp解决跨域问题_第1张图片
上图中有“红色标记”的栗子都是不同源的情形。总的来说,协议名、域名、端口号任意一项不同就不同源。

1.3 跨域问题的解决方案

  • 很多项目中,为了实现前后端应用服务器分离,会特意将前端静态资源(html/css/js等)与后台数据接口 分处在不同的服务器上,所以域名/ip或端口号必然不相同,这就导致了“跨域请求问题”。
  • 跨域问题的解决方案有:
    – 代理请求
    –JSONP
    –CORS

本文主要将jsonp方案解决跨域问题,其他方案学习透彻了再来总结。

1.4 什么是JSONP

  • JSONP(json with padding)是json的一种使用模式。
  • 通过上面的学习,我们已经知道,由于同源策略浏览器会禁止JS跨域。
    但是,我们知道script标签是允许跨域请求的。利用这个特性,客户端使用script代替XHR( XMLHttpRequest)发起跨域请求,服务器在json响应数据前后填充一些额外的内容,就称为“填充式JSON”——JSONP

2. JSONP方案具体实现

JSONP实现跨域请求的原理就是动态创建script标签,利用“src”不受同源策略约束的性质来实现跨域获取数据。
菜鸟教程提供了一个链接,我们可以用它练练手~
链接:https://www.runoob.com/try/ajax/jsonp.php?jsoncallback=callbackFunction

2.1动态创建script标签

下面栗子很简单,就不细说了~

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>JSONP 实例</title>
</head>
<body>
<script>
  function callbackFunction(data){
     
    console.log("i got it");
    console.log(data);
  }
</script>
<script>
  window.onload=function(){
     
    var script=document.createElement("script");
    script.src="https://www.runoob.com/try/ajax/jsonp.php?jsoncallback=callbackFunction";
    document.head.append(script)}
</script>
</body>
</html>

2.2 用jQuery中$.getJSON()实现JSONP

  • $.getJSON()方法允许通过使用JSONP形式的回调函数来加载其他网域的JSON数据
  • 使用$.getJSON()方法实现跨域请求,需要在请求路径URL后增加callback=?, jQuery将自动替换“?”为正确的函数名,以执行回调函数。

注:下面代码中路径后是jsoncallback=?,因为服务端的代码中回调函数名为jsoncallback,前后端应该是一致的

记得引入jQuery文件!

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>JSONP 实例</title>
    <script src="https://cdn.static.runoob.com/libs/jquery/1.8.3/jquery.js"></script>    
</head>
<body>
<script>
$.getJSON("https://www.runoob.com/try/ajax/jsonp.php?jsoncallback=?",function(data){
     console.log(data);})
</script>
</body>
</html>

2.3 用jQuery中$.ajax()实现JSONP

$.ajax()方法同样可以实现JSONP跨域请求,我们主要来看看它的一些选项参数:

  • url:请求地址
  • type:请求方式
  • dataType:“jsonp” 必写,设置服务器端返回的数据类型,这里是"jsonp"
  • jsonp:获得jsonp回调函数名的参数名,这个值用于代替"callback=?"(本例就是用"jsoncallback=?“代替了"callback=?”),一般默认都是callback
  • jsonCallback:可选,为JSONP请求指定一个回调函数名,这个值将代替jQuery自动生成的随机函数名(就是代替"callback=?"中的问号)
  • success:请求成功后的回调函数。

知道这些选项参数的意思了,我们再看看上面给到的那个链接:

https://www.runoob.com/try/ajax/jsonp.php?jsoncallback=callbackFunction

我们看到调用的url中,jsoncallback参数告诉服务器,我的本地回调函数叫做callbackFunction,让服务器请把查询结果传入这个函数中。服务器传递给callbackFunction函数json格式的数据:callbackFunction([“customername1”,“customername2”])

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>JSONP 实例</title>
    <script src="https://cdn.static.runoob.com/libs/jquery/1.8.3/jquery.js"></script>    
</head>
<body>
<script>
$.ajax({
     
  url: "https://www.runoob.com/try/ajax/jsonp.php",
  type: "get",
  dataType: "jsonp",
  jsonp: "jsoncallback",
  success: function(data){
     
    console.log(data);
  }
})
</script>
</body>
</html>

2.4 总结:

  • ajax和jsonp本质上是不同的东西。ajax的核心是通过XmlHttpRequest获取非本页内容,而jsonp的核心则是动态添加script标签来调用服务器提供的js脚本。
  • JSONP方案属于客户端直接请求,不存在二次请求的问题;但是,不足是script标签只能发起get请求。

你可能感兴趣的:(jQuery,jsonp,json,javascript,jquery,ajax跨域问题)