解决Ajax同源政策的方法【JSONP + CORS + 服务器端解决方案】
解决Ajax同源政策的方法
使用JSONP解决同源限制问题
jsonp是json with padding的缩写,它不属于Ajax请求,但它可以模以Ajax请求。\
步骤
1.将不同源的服务器端请求地址写在script标签的src属性中
	<script src="https://i.cnblogs.com"></script>
		<script src="http://jquery.com/"></script>
2.服务器端响应数据必须是一个函数的调用,真正要发送给客户端的数据需要作为函数调用的参数。
const data = 'fn({name: 'lvhang', age: '23'})'
	res.send();
3.在客户端全局作用域下定义函数fn]【这个函数必须定义在script标签的前面!】
	function fn (data) {}
4.在fn函数内部对服务器端返回的数据进行处理
function fn (data) {
	console.log(data)
}
实际上JSONP的核心就是利用script标签可以向非同源的服务器发送请求的特性!在服务器端返回函数调用的代码!
实际测试
第一步:还是得需要有两个不同源的服务器并开启!【我这里的一号服务器是端口为3003的, 二号是端口为3001的!】
第二步:你还是在二号服务器上写一个测试路由

第三步:在一号服务器这儿的lvhang文件夹下新建一个html文件!名字随便起【好歹让他有意义吧!】

<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<meta name="viewport" content="width=device-width, initial-scale=1.0">
	<title>Document</title>
</head>
<body>
	<script>
		function fn (data, succ) {
			console.log('客户端的函数fn被调用了!')
			console.log(data, succ)
		}
		</script>
		<!-- 1.将非同源服务器端的请求地址写在script标签的src属性中 -->
		<!-- 下面的 标签返回一个函数调用的代码!-->
	<script src="http://localhost:3001/test"></script>
</body>
</html>
- 第四步:在浏览器中查看效果!

 
看到上面的代码,说明我们已经成功的获取到了不同源的下信息了!
JSONP代码的核心优化!
1.客户端需要将函数名称传递到服务器端。
一号服务器的优化前后代码对比:
- 优化前:
 
	<script>
		function fn (data, succ) {
			console.log('客户端的函数fn被调用了!')
			console.log(data, succ)
		}
		</script>
		<!-- 1.将非同源服务器端的请求地址写在script标签的src属性中 -->
		<!-- 下面的 标签返回一个函数调用的代码!-->
	<script src="http://localhost:3001/test"></script>
- 优化后:
 
<script>
		function fn (data, succ) {
			console.log('客户端的函数fn被调用了!')
			console.log(data, succ)
		}
		</script>
		<!-- 1.将非同源服务器端的请求地址写在script标签的src属性中 -->
		<!-- 下面的 标签返回一个函数调用的代码!-->
	<script type="text/javascript" src="http://localhost:3001/better?callback=fn">
		</script>
二号服务器的代码变化:
// 在二号服务器的app.js中写一个测试路由!让第一个同源来访问!
app.get('/test', (req, res) => {
	// 要在这儿返回一个函数调用的代码!
	const result = 'fn({name: "lvhang"}, {test: "如果你能看到这条消息,说明你已经解决了同源的问题!你用的或许是jsonph or CROS但是,这已经不重要了!"})';
	res.send(result)
})
app.get('/better', (req, res) => {
	// 接收客户端传递过来的函数名称
	const fnName = req.query.callback;
	// 将函数名称对应的函数调用代码返回给客户端!
	const result = fnName + '({name: "lvhang"}, {test: "如果你能看到这条消息,说明你已经解决了同源的问题!你用的或许是jsonph or CROS但是,这已经不重要了!"})';
	res.send(result)
})
2.将script请求的发送变成动态请求。
一号服务器的优化前后代码对比:
- 优化前:
 
<script>
		function fn (data, succ) {
			console.log('客户端的函数fn被调用了!')
			console.log(data, succ)
		}
		</script>
		<!-- 1.将非同源服务器端的请求地址写在script标签的src属性中 -->
		<!-- 下面的 标签返回一个函数调用的代码!-->
	<script src="http://localhost:3001/test"></script>
- 优化后:
 
<button id="btn">点击我发送请求!</button>
	<script>
		function fn (data, succ) {
			console.log('客户端的函数fn被调用了!')
			console.log(data, succ)
		}
		</script>
		<!-- 1.将非同源服务器端的请求地址写在script标签的src属性中 -->
		<!-- 下面的 标签返回一个函数调用的代码!-->
	<script type="text/javascript">
		const btn = document.getElementById('btn');
		btn.onclick = function () {
			console.log(123)
			// 创建script标签
			const script = document.createElement('script');
			// 设置src属性
			script.src = 'http://localhost:3001/test';
			document.body.appendChild(script);
			// 为script标签添加onload事件
			script.onload = function () {
				// 将body标签中的script标签删除掉!
				document.body.removeChild(script);
			}
		}
		</script>
最主要的区别就是我们可以控制什么时候发送非同源的请求了!动态的发送请求!
实现非同源请求的第二种方法!CORS
CORS 跨域资源共享
CORS:全称为Cross-origin resource sharing,即跨域资源共享,它允许浏览器向跨域服务器发送Ajax请求,克服了Ajax只能同源使用的限制。
以下图片来自黑马程序员2019前端

get和post设置在响应头当中!
他和JSONP的不同就是它可以使用原生的Ajax代码实现跨域请求!
1在一号服务器写下常规的Ajax请求的代码!连封装都没有封装过的那种,以示原生的力量!
<button id="btn">点击我发送请求</button>
	<script type="text/javascript">
			let btn = document.getElementById('btn');
			btn.onclick = function () {
				// 1 创建Ajax对象
				let xhr = new XMLHttpRequest();
				// 2 告诉Ajax对象要想哪儿发送请求,以什么方式发送请求
				// 1)请求方式2)请求地址
				xhr.open('get', 'http://localhost:3001/cross');
				// 发送请求
				xhr.send();
				// 获取服务器端响应到客户端的数据!
					xhr.onload = function() {
					console.log(xhr.responseText)
				}
			};
		</script>
在二号服务器这里写如下的路由
app.get('/cross', (req, res) => {
	// 允许哪些客户端访问我!
	// 第一个参数就是响应头的属性名称
	// 第二个参数就是响应头的属性名称对应的值!
	// * 代表允许所有的客户端访问我!
	res.header('Access-Control-Allow-Origin', '*')
	// 允许客户端使用哪些请求方法访问我!
	res.header('Access-Control-Allow-Methods', 'get, post')
	res.send('您成功的使用CROS跨域资源共享的方法解决了同源的问题!')
})
这样就可以实现跨域访问了!!!!!!=但是这儿有一个严重的问题!就是这还只是一个路由, 那不止一个呢?!所以为了提高效率,我们应该在服务器代码中加入拦截请求, 为所有的请求加上响应头, 这样就不用为每一个路由分别配置跨域访问的代码了!!
app.get('/cross', (req, res) => {
	// 允许哪些客户端访问我!
	// 第一个参数就是响应头的属性名称
	// 第二个参数就是响应头的属性名称对应的值!
	// * 代表允许所有的客户端访问我!
	// res.header('Access-Control-Allow-Origin', '*')
	// 允许客户端使用哪些请求方法访问我!
	// res.header('Access-Control-Allow-Methods', 'get, post')
	res.send('您成功的使用CROS跨域资源共享的方法解决了同源的问题!')
})
// 拦截所有的请求为他们加上响应头!
// next 控制权函数
app.use(function (req, res, next) {
	// 允许哪些客户端访问我!
	// 第一个参数就是响应头的属性名称
	// 第二个参数就是响应头的属性名称对应的值!
	// * 代表允许所有的客户端访问我!
	res.header('Access-Control-Allow-Origin', '*')
	// 允许客户端使用哪些请求方法访问我!
	res.header('Access-Control-Allow-Methods', 'get, post')
	next();
})
访问非同源数据 服务器端解决方案
同源政策是浏览器给予Ajax技术的限制,服务器端是不存在同源攻策限制。
一号服务器html文件中的代码没有变化 如下:
	<button id="btn">点击我发送请求</button>
	<script type="text/javascript">
			let btn = document.getElementById('btn');
			btn.onclick = function () {
				// 1 创建Ajax对象
				let xhr = new XMLHttpRequest();
				// 2 告诉Ajax对象要想哪儿发送请求,以什么方式发送请求
				// 1)请求方式2)请求地址
				xhr.open('get', 'http://localhost:3003/server');
				// 发送请求
				xhr.send();
				// 获取服务器端响应到客户端的数据!
					xhr.onload = function() {
					console.log(xhr.responseText)
				}
			};
		</script>
一号服务器端的代码变化蛮大的!如下:
引入了一个新的模块 request【这个模块要用npm下载偶!】
// 引用request模块! 返回一个request函数
// 向其他服务器端请求数据的模块!服务器端是不受同源政策的影响的!
const request = require('request');
app.get('/server', (req, res) => {
	// 第一个参数请求地址
	// 第二个参数是回调函数!
	// 有三个参数 1 err 错误对象
	// 2 response 服务器端的一些响应信息!
	// 3 body 就是我们需要的信息!
	request('http://localhost:3001/cross', (err, response, body) => {
		console.log(body)
		res.send(body)
	})
})
二号服务端的代码没有变化!
app.get('/cross', (req, res) => {
	// 允许哪些客户端访问我!
	// 第一个参数就是响应头的属性名称
	// 第二个参数就是响应头的属性名称对应的值!
	// * 代表允许所有的客户端访问我!
	// res.header('Access-Control-Allow-Origin', '*')
	// 允许客户端使用哪些请求方法访问我!
	// res.header('Access-Control-Allow-Methods', 'get, post')
	res.send('您成功的使用CROS跨域资源共享的方法解决了同源的问题!')
})
												
											解决Ajax同源政策的方法【JSONP + CORS + 服务器端解决方案】的更多相关文章
- 破解浏览器同源政策利器之JSONP
		
本文是在了解了浏览器的同源规则之后,学习了破解这个规则的一个简单有效的方法->JSONP.主要通过阮一峰老师的博客学习 浏览器的同源规则 有这样一个背景,如果你通过银行的网站进行的取钱的交易,而 ...
 - 跨域请求解决方法(JSONP, CORS)
		
1.跨域 假设我们页面或者应用部署在 http://www.aaa.com 上了,而我们打算从 http://www.bbb.com 请求提取数据.一般情况下,如果我们直接使用 AJAX 来请求将会失 ...
 - django上课笔记7-jQuery Ajax 和 原生Ajax-伪造的Ajax-三种Ajax上传文件方法-JSONP和CORS跨域资源共享
		
一.jQuery Ajax 和 原生Ajax from django.conf.urls import url from django.contrib import admin from app01 ...
 - 解决ajax跨域的方法原理详解之Cors方法
		
1.神马是跨域(Cross Domain) 对于端口和协议的不同,只能通过后台来解决. 一句话:同一个ip.同一个网络协议.同一个端口,三者都满足就是同一个域,否则就是 跨域问题了.而为什么开 ...
 - webapi 解决ajax跨域请求问题
		
webapi在配置文件中加入这几句就可以解决ajax(同源策略是JavaScript里面的限制,其他的编程语言,比如在C#,Java或者iOS等其他语言中是可以调用外部的WebService,也就是 ...
 - 跨域的两种解决方法jsonp和CORS
		
1.跨域 什么是跨域? 当你请求的url是不同源的数据的时候,浏览器一般会抛出请求跨域的错误,如下图: 造成跨域的原因? 即你违反了浏览器的同源策略的限制=>阻止一个域的js脚本和另外一个域的内 ...
 - 跨域问题及其解决方法(JSONP&CORS)
		
一.什么是跨域 当a.qq.com域名下的页⾯或脚本试图去请求b.qq.com域名下的资源时,就是典型的跨域行为.跨域的定义从受限范围可以分为两种,⼴义跨域和狭义跨域. (一)广义跨域 ⼴义跨域通常包 ...
 - 跨域访问 - 跨域请求  同源策略概念对跨域请求的影响 及几种解决跨域请求的方法如 jsonp
		
为什么会设置同源策略 > 适用于浏览器的一种资源访问策略 > 同源策略(Same origin policy)是一种约定,它是浏览器最核 心也最 基本的安全功能,如果缺少了同源策略,则浏览 ...
 - jquery ajax跨域的完美解决方法(jsonp方式)
		
ajax跨域请求的问题,JQuery对于Ajax的跨域请求有两类解决方案,不过都是只支持get方式,接下来为大家详细介绍下客户端JQuery.ajax的调用代码 今天在项目中需要做远程数据加载 ...
 
随机推荐
- 关于c语言单项链表尾添加
			
犹豫了几天,看了很多大牛写的关于c语言链表,感触很多,终于下定决心,把自己对于链表的理解随之附上,可用与否,自行裁夺.由于作者水平有限也是第一次写,不足之处,竭诚希望得到各位大神的批评指正.制作不易, ...
 - 【Azure Service Bus】 Service Bus如何确保消息发送成功,发送端是否有Ack机制 
			
问题描述 Service Bus如何确保消息发送成功,发送端是否有Ack机制(是否有回调API告诉发送端,服务端已经收到消息)?根据对.NET发送Service Bus消息代码的分析,发送方法queu ...
 - 【剑指offer】03 从尾到头打印链表
			
题目地址:从尾到头打印链表 题目描述 输入一个链表,按链表从尾到头的顺序返回一个ArrayList. 时间限制:C/C++ 1秒, ...
 - Tensorflow Windows安装
			
操作系统: Windows 7 安装步骤 Step 1: 安装Tensorflow支持的Python版本,配置环境变量 目前,Tensorflow支持: Python 3.5.x 64-bit fro ...
 - 从零开始手把手教你使用javascript+canvas开发一个塔防游戏01地图创建
			
项目演示 项目演示地址: 体验一下 项目源码: 项目源码 代码结构 本节做完效果 游戏主页面 index.html <!DOCTYPE html PUBLIC "-//W3C//DTD ...
 - 聊两句XSS(跨站脚本攻击)
			
XSS(跨站脚本攻击),聊两句,五毛的. XSS的危害: 窃取Cookie,盗用用户身份信息 这玩意儿是大多数XSS的目标,也好解决,可以先治个标,直接设置HttpOnly=true ,即不允许客户端 ...
 - ESP32 BLE蓝牙 微信小程序通信发送大于20字符数据
			
由于微信小程序只支持BLE每次发送数据不大于20个字节,ESP32则有经典蓝牙.低功耗蓝牙两种模式. 要解决发送数据大于20个字节的问题,最简单实用的方式就是分包发送.如下图所示: 1.什么起始字符和 ...
 - 用Margin还是用Padding的区别
			
用margin还是用padding这个问题是每个学习CSS进阶时的必经之路. CSS边距属性定义元素周围的空间.通过使用单独的属性,可以对上.右.下.左的外边距进行设置.也可以使用简写的外边距属性同时 ...
 - sql文件转换为excel文件
			
最近经常需要把sql整理成excel,本人比较懒,所以写一个小工具,用到了jxl包.以前没有接触过,正好了解一下. 一.基础知识 jxl操作excel包括对象 Workbook,Sheet ...
 - Docker进行MySQL主从复制操作
			
Docker的相关操作 与 Docker下MySQL容器的安装 https://www.cnblogs.com/yumq/p/14253360.html 本次实验我是在单机状态下进行mysql的主从复 ...