使用JSONP跨域发起ajax请求原理

版权声明:本文为博主原创文章,如有转载请注明出处,谢谢。 https://blog.csdn.net/pdsu161530247/article/details/82189866

1.jsonp介绍

Jsonp(JSON with Padding) 是 json 的一种"使用模式",可以跨域读取数据。

为什么我们从不同的域(网站)访问数据需要一个特殊的技术(JSONP )呢?这是因为同源策略。

同源策略,它是由Netscape提出的一个著名的安全策略,现在所有支持JavaScript 的浏览器都会使用这个策略。

1.1什么是同源策略

两个页面地址中的协议、域名和端口号一致,则表示同源。

例如该地址 https://www.google.com 和以下地址对比

地址 同源 原因
http://www.google.com 协议不一致
https://google.com 域名不一致
https://www.google.com:81 端口号不一致
https://www.google.com/a/s.html 协议,域名和端口号都一致

同源策略的限制:

  1. 存储在浏览器中的数据,如localStroage、Cookie和IndexedDB不能通过脚本跨域访问

  2. 不能通过脚本操作不同域下的DOM

  3. 不能通过ajax请求不同域的数据

1.2为什么要同源策略

设置同源限制主要是为了安全,如果没有同源限制存在浏览器中的cookie等其他数据可以任意读取,不同域下DOM任意操作,Ajax任意请求的话如果浏览了恶意网站那么就会泄漏这些隐私数据。

Cookie一般用来保存登录状态。在登录一个银行网站后此时浏览器中就保存了登录的状态,同时浏览了恶意网站,这时Cookie的信息没有同源限制的话恶意网站就可以获取这些Cookie信息来达到不为人知的目的。

如果可以操作不同域下的DOM可以用如下方式完成盗取信息。在自己的网站上嵌入一个iframe地址设置成银行地址,然后让iframe全屏显示,当你一不小心上当了输入你账号密码,我就可以通过DOM操作获取到输入的信息。

Ajax的限制同Cookie,如果带上Cookie去跨域访问接口就可以通过程序的验证被认为身份是合法的。

既然瞥见危害一角自然要严加防范,限制非同源操作。

1.3怎么规避同源策略

解决方法有很多,我这里使用的是jsonp。

更多方法参考:https://blog.csdn.net/letterTiger/article/details/79520375 

目录1.1、1.2的内容也是引入这个链接里面的,确实写的不错。

2.jsonp跨域发起ajax请求的简单例子

2.1准备工作

首先需要准备一台nginx,分别配置监听81端口和82端口,模拟两个不同的网站。

worker_processes  1;
events {
    worker_connections  1024;
}
http {
    include       mime.types;
    default_type  application/octet-stream;
    sendfile        on;
    keepalive_timeout  65;
    server {
        listen       81;
        server_name  localhost;
        location / {
            root   F:/nginx/html;
        }   
    }
	server {
        listen       82;
        server_name  localhost;
        location / {
            root   F:/nginx/html;
        }     
    }
}

web1

web1_js.js内容:

function fun(data){
	alert(data);
}

web1_json.json内容:

{
	"id":1
}

web2

web2.html内容:

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<script type="text/javascript" src="./jquery-1.6.4.js"></script>
<script type="text/javascript">
	/*function fun(data) {
		alert(data.id);
	}*/

	$(function() {
		$.ajax({
			url : "http://localhost:81/web1/web1_json.json",
			type : "get",
			dataType : "json",
			success : function(data) {
				alert("success");
			}
		});
		 /*$.ajax({
			url:"http://localhost:81/web1/web1_js.js",
			type:"get",
			dataType:"script",
			success:function(data){
				alert("success");
			}
		}); */
	})
</script>
</head>
<body>

</body>
</html>

2.2测试

我们使用web2.html中的ajax作为网站一的跨域方,web1中的js与json作为被请求方

使用浏览器直接访问web1中的json,可以成功访问

使用web2的ajax请求加载json,会出现错误,错误原因就是因为同源策略,ajax无法请求不同域的数据(比如:json、xml之类的)

我们使用第二个ajax,dataType:"script",加载js看看会出现什么情况

可以成功加载js

所以我们考虑,将第一个ajax的dataType:"json",改为dataType:"script"。虽然ajax请求的是json数据,但是我们为了跨域,

将dataType:"script",让对方以为我们是加载js。

是可以请求成功,但是好像拿不到json数据啊?

我们将web1_json.json改成一个函数调用,把json作为参数放到里面。

fun({
	"id":1
})

在ajax请求方,写一个fun函数

function fun(data) {
    alert(data.id);
}

ajax可以成功加载json。

3.总结

大概意思就是:直接使用ajax是无法请求非同源站点的json、xml之类,但是可以加载js,使用dataType:"script"将json当做js加载,但是浏览器拿到这个json它会当做js,所以虽然可以加载成功,但是我们也拿不到这个json。所以可以将json封装成一个fun(json),然后在本地写一个function fun(data),浏览器就会将请求的fun(json)当做本地的fun函数来调用。最后要使用jsonp的形式,必须服务端支持jsonp,上面的json{"id":1},是服务端拼装成的fun({"id":1});

猜你喜欢

转载自blog.csdn.net/pdsu161530247/article/details/82189866