js读取本地json跨域问题

jsonp解决跨域

1. 问题

使用ajax方式读取本地json文件,谷歌浏览器会提示跨域错误,导致获取不到json数据

1
2
3
4
5
6
7
var request = new XMLHttpRequest();
request.open("get","plan.json");
request.send(null);
request.onload=function(){
var json = JSON.parse(request.responseText);
console.log(json);
}

Access to XMLHttpRequest at 'file:///Users/Learning/Downloads/index/plan.json' from origin 'null' has been blocked by CORS policy: Cross origin requests are only supported for protocol schemes: http, data, chrome, chrome-extension, chrome-untrusted, https.

1.1. 跨域问题

跨域是指从一个域名的网页去请求另一个域名的资源。由浏览器的同源策略造成的,是浏览器对JavaScript施加的安全限制。跨域的严格一点的定义是:只要 协议,域名,端口有任何一个的不同,就被当作是跨域

所谓同源是指 域名,协议,端口均相同。这里说的js跨域是指通过js在不同的域之间进行数据传输或通信,比如用ajax向一个不同的域请求数据。

1.1.1. Ajax为什么不能跨域?

Ajax其实就是向服务器发送一个GET或POST请求,然后取得服务器响应结果,返回客户端。理论上这是没有任何问题的,只是服务端响应数据返回给浏览器的时候,浏览器根据响应头的Access-Control-Allow-Origin字段的值来判断是否有权限获取数据,一般情况下,服务器端如果没有在这个字段做特殊处理的话,跨域是没有权限访问的,所以响应数据被浏览器给拦截了,所以在ajax回调函数里是获取不到数据的。所以现在ajax跨域的问题可以转化为数据怎么拿回客户端的问题

1.1.2. js可以被任意网站加载

web页面可以加载放在任意站点的js、css、图片等资源,不会受到”跨域”的影响。将数据放到第三方站点的js中将数据带到客户端

getjs.js

1
2
3
function getData() {
return "get data";
}

index.html

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<!DOCTYPE html>
<html>
<head>
<title>本地站点</title>
<meta charset="UTF-8">
<script type="text/javascript" src="getjs.js"></script>
</head>
<script type="text/javascript">
var data = getData();
alert(data);
</script>
<body>

</body>
</html>

可以显示

如何根据需要发送请求和获取请求的结果呢?来认识一下JSONP

2. 解决

2.1. JSONP

JSONP(JSON with Padding)是JSON的一种“使用模式”,可用于解决主流浏览器的跨域数据访问的问题。它允许在服务器端集成<script>返回至客户端,通过javascript callback的形式实现跨域访问

仅适用于GET请求

<script> 标签是不受同源策略的限制的,它可以载入任意地方的 JavaScript 文件,而并不要求同源。

和服务端约定好一个函数名,当请求文件的时候,服务端返回一段 JavaScript。这段 JavaScript 调用了我们约定好的函数,并且将数据当做参数传入。JSON 的数据格式和 JavaScript 语言里对象的格式正好相同。所以在我们约定的函数里面可以直接使用这个对象。

2.1.1. 使用

plan.json

1
2
3
4
5
6
7
8
createTable({
"plan":[
{"index":"1","site":"AAA","content":"content1","person":"A1"},
{"index":"2","site":"BBB","content":"content2","person":"A2"},
{"index":"3","site":"CCC","content":"content3","person":"A3"},
{"index":"4","site":"DDD","content":"content4","person":"A4"}
]
})

index.html

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<!DOCTYPE html>
<html>
<head>
<title>本地站点</title>
<meta charset="UTF-8">

</head>
<script type="text/javascript">
function createTable(data){
console.log(data);
}
</script>
<body>
<!--src ? 之前为文件地址,? 之后为回调函数callback名称,回调函数可以简写为cb,然后回调函数名称要与JSON文件中的名称一致 -->
<script type="text/javascript" src="plan.json?cb=createTable"></script>
</body>
</html>

显示

2.1.2. 流程

2.1.3. 注意

  • 一定要在json文件的外部用函数名+()套住;
  • js中的回调函数一定要与json中函数名相同;
本文结束  感谢您的阅读