前言
同源策略的限制,使得ajax无法发出跨域请求。在许多情况下,我们需要让ajax支持跨域。以下是其中一种解决方案(JSONP)。JSONP解决了跨域数据访问的问题。
在html中,具有src属性的标签支持跨域,例如<script>、<img>。
其中,<script>特别适合解决ajax跨域问题。首先当我们通过src引入js文件时,便会对其中的js代码进行执行。我们知道json是文本,js也是文本,那我们就把json伪装成js。也就是将请求地址放入到<script>标签的src中,那怎么样将json伪装成js,且能够在浏览器获取json数据呢?
答案就是通过调用方法,将json伪装成调用方法的语句,其中真正的json数据作为该方法的参数,当通过script标签引入这些文本时,就相当于执行了这个方法。而在前端,我们只需要编写对应的方法,而从服务器发过来的script脚本将会执行该方法并且传入真正的json数据。这样,就可以轻松实现跨域访问了。以下为大概流程图(丑):
实现
- 使用javascript与php简单实现如下:
前端代码:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>jsonp</title> </head> <body> <script> ajax("http://localhost/province/json.php"); function ajax(url) { var script = document.createElement("script"); script.src = url + "?jsonp=callback"; document.getElementsByTagName("head")[0].append(script); }
// 编写回调函数 function callback(data) { alert(data.msg); } </script> </body> </html>
后端代码:
<?php header("Content-Type", "application/json"); $fun = $_REQUEST["jsonp"]; // 获取调用的方法名 echo "$fun({'msg': 'jsonp'});";
- 使用jquery
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>jsonp</title> </head> <body> <script src="http://cdn.bootcss.com/jquery/2.2.2/jquery.js"></script> <script> $.ajax({ url: "http://localhost/province/json.php", type: "get", data: {}, dataType: "jsonp", jsonp: "jsonp", success: function (data) { alert(data.msg); }, error: function () {//...} }); </script> </body> </html>
使用jquery提供的$.ajax可以快速实现跨域请求。首先设置dataType为"jsonp",表示使用jsonp。参数jsonp是传递将被调用函数名,服务器通过使用该属性的值来获得函数名。使用jquery后也不需要自己写调用函数了,它将由jquery自动生成,正在的json数据将通过success属性回调自定义函数进行传递。