1.*****实现跨域请求的方案--JSONP*******
JSON with Padding,是一种借助于 script 标签发送跨域请求的技巧。
其原理就是在客户端借助 script 标签请求服务端的一个地址,服务端的这个地址返回一段带有调用某个全局函数调用的 JavaScript 脚本(而非一段 HTML),将原本需要返回给客户端的数据通过参数传递给这个函数,函数中就可以得到原本服务端想要返回的数据。
以后绝大多数情况都是采用 JSONP 的手段完成不同源地址之间的跨域请求
*********
***********************演示跨域的准备工作:1**********************************************
- 创建两个网站A和B(其实就是A网页和B网页)
- A网站的端口是3000
- B网站的端口是4000
*************
具体做法:
1. 然后A网站中,能够显示jsonp.html即可
. // A网站中的 a.js
// 开启服务器
const express = require('express');
const app = express();
app.listen(3000, () => console.log('3000 start'));
app.get('/jsonp.html', (req, res) => {
res.sendFile(__dirname + '/jsonp.html');
});
2.jsonp.html中,使用script标签的src属性指向B网站的getData接口,来向B网站发起请求
json.html中的代码
<script src="http://127.0.0.1:4000/getData"></script>
3.B网站配合A网站,实现getData接口
// B 网站中的 b.js
// 开启服务器
const express = require('express');
const app = express();
app.listen(4000, () => console.log('4000 start'));
// 配合3000网站,编写getData接口
app.get('/getData', (req, res) => {
res.end('alert(123)');
});
********得出以下结论
浏览器访问:127.0.0.1:3000/jsonp.html 当访问这个页面的时候,浏览器就会解析它里面的script标签,从而向B网站发起请求。
B网站返回的是 一段js代码,这个代码会在显示jsonp.html 中执行。
**************************************2*************************************
跨域请求的时候,获取B网站提供的数据:
既然B网站返回的js代码,在A网站的页面中可以运行。所以B网站返回一个调用函数的js代码,看看A网站能不能正常运行。
2.1所以在B网站的getData接口返回一个函数调用的代码:
// 配合3000网站,编写getData接口
app.get('/getData', (req, res) => {
// res.end('alert(123)'); // 这里返回给A网站的 js代码,会在A网站的页面中运行
res.end('abc()'); // 告诉A网站的页面,执行一个abc函数
});
2.2刷新jsonp.html页面会报错,找不到abc函数,为了不报错,所以在jsonp.html 中,要提前准备一个abc函数
<script>
// A网站要提前准备一个abc函数,因为下面的请求,B网站告诉我们要执行abc
// 如果这里没有abc函数,将会报错
function abc () {
alert('hello 我是abc');
}
</script>
<script src="http://127.0.0.1:4000/getData">
</script>
刷新jsonp.html 不会报错,并且会执行abc函数。
***********************************3*****************************
上面B网站告诉A网站要执行abc函数,结果确实可以在A网站中执行abc函数。所以进一步想象,如果调用B网站告诉A网站调用abc函数的的时候,并且传递参数可不可以?经过测试,可以。所以就可以把B网站中的数据当做参数传递给A网站。
B网站中的b.js代码:
// 配合3000网站,编写getData接口
app.get('/getData', (req, res) => {
// res.end('alert(123)'); // 这里返回给A网站的 js代码,会在A网站的页面中运行
// res.end('abc()'); // 告诉A网站的页面,执行一个abc函数
let data = ['apple', 'banana', 'orange'];
// 告诉A网站的页面,执行一个abc函数,并且给abc传了参数,参数就是数据
res.end('abc(' + JSON.stringify(data) + ')');
});
A网站中的jsonp.html 代码:
<script>
// A网站要提前准备一个abc函数,因为下面的请求,B网站告诉我们要执行abc
// 如果这里没有abc函数,将会报错
/* function abc () {
alert('hello 我是abc');
} */
// B网站调用abc函数的时候,传递了B网站中的数据,所以这里设置形参,来接收数据
function abc (x) {
console.log(x);
}
</script>
<script src="http://127.0.0.1:4000/getData">
</script>
可以实现...
***********************************4********************************
解决一个弊端:
如果A网站中原来就有一个abc函数,下面在定义abc将会报错。解决办法就是给B网站传递一个callback参数,参数的值就是要使用的函数名。这个函数名由发请求的A网站自己来决定。B网站获取url中的callback参数的值,然后把它当做函数的名字来调用即可:
A网站的 jsonp.html 代码:
<script>
// 根据callback的值abcd,定义abcd函数
function abcd (x) {
console.log(x);
}
</script>
<script src="http://127.0.0.1:4000/getData?callback=abcd"></script>
B网站的 b.js 代码:
// 配合3000网站,编写getData接口
app.get('/getData', (req, res) => {
// res.end('alert(123)'); // 这里返回给A网站的 js代码,会在A网站的页面中运行
// res.end('abc()'); // 告诉A网站的页面,执行一个abc函数
let data = ['apple', 'banana', 'orange'];
// 告诉A网站的页面,执行一个abc函数,并且给abc传了参数,参数就是数据
// res.end('abc(' + JSON.stringify(data) + ')');
// B网站获取地址栏的callback参数,它就是需要调用的函数名
// 使用node中提供的url模块来获取地址栏的callback参数
********4.1这个可以快速得到
console.log(req.query.callback); // 使用express提供的方法获取地址栏的参数
********4.2
这个用这种方式获取到
console.log(req.url); // /getData?callback=abcd
let myUrl = new URL(req.url, 'http://www.ccc.com');
let fn = myUrl.searchParams.get('callback'); // 这就是A网站中传递的函数名abcd
res.end(fn + '(' + JSON.stringify(data) + ')');
});
*****************************5*************************
jQuery封装的ajax方法跨域请求:
5.1******在3000网站中,jquery.html 中引入一个jQuery文件,为了方便(引入自己的jQuery,自己就得写处理静态资源文件的代码),引入的是百度提供的jquery
5.2*******使用jQuery提供的ajax方法,实现跨域访问
<!-- 使用jQuery提供的ajax方法,实现跨域请求 -->
<!-- 下面引入百度提供的jQuery,需要联网 -->
<第一种>
<script src="http://libs.baidu.com/jquery/2.1.4/jquery.min.js"></script>
<script>
$.ajax({
type: 'GET',
// data: {}, // 发送给4000(B)网站的数据
url: 'http://127.0.0.1:4000/getData?callback=?', // ? 可以理解为下面的success方法。
success: function (result) {
// result就是4000服务器返回的数据
console.log(result);
},
dataType: 'jsonp' // 必须要指定dataType为jsonp
});
</script>
<第二种>
使用jQuery的$.get方法也是可以的:
$.get('http://127.0.0.1:4000/getData', {callback: '?'}, function (res) {
console.log(res);
}, 'jsonp');
********************************************6*********************
实现跨域请求的方案--CORS
通过在==被==请求的路由中设置header头,可以实现跨域。不过这种方式只有最新的浏览器(IE10)才支持。
Cross Origin Resource Share,跨域资源共享
被请求的网页(B网页)
// 使用CORS 来允许跨域
app.get('/cors', (req, res) => {
// res.setHeader('Access-Control-Allow-Origin', '允许来请求的域名');
// res.setHeader('Access-Control-Allow-Origin', '*');
res.setHeader('Access-Control-Allow-Origin', 'http://127.0.0.1:3000');
res.end('hello');
});
这种方案无需客户端作出任何变化(客户端不用改代码),只是在被请求的服务端响应的时候添加一个 Access-Control-Allow-Origin 的响应头,表示这个资源是否允许指定域请求。
Ajax跨域请求.
最新推荐文章于 2022-07-05 08:58:56 发布