Ajax跨域请求.

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 的响应头,表示这个资源是否允许指定域请求。



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值