Java自学者论坛

 找回密码
 立即注册

手机号码,快捷登录

恭喜Java自学者论坛(https://www.javazxz.com)已经为数万Java学习者服务超过8年了!积累会员资料超过10000G+
成为本站VIP会员,下载本站10000G+会员资源,会员资料板块,购买链接:点击进入购买VIP会员

JAVA高级面试进阶训练营视频教程

Java架构师系统进阶VIP课程

分布式高可用全栈开发微服务教程Go语言视频零基础入门到精通Java架构师3期(课件+源码)
Java开发全终端实战租房项目视频教程SpringBoot2.X入门到高级使用教程大数据培训第六期全套视频教程深度学习(CNN RNN GAN)算法原理Java亿级流量电商系统视频教程
互联网架构师视频教程年薪50万Spark2.0从入门到精通年薪50万!人工智能学习路线教程年薪50万大数据入门到精通学习路线年薪50万机器学习入门到精通教程
仿小米商城类app和小程序视频教程深度学习数据分析基础到实战最新黑马javaEE2.1就业课程从 0到JVM实战高手教程MySQL入门到精通教程
查看: 393|回复: 0

ajax跨域问题解决方案(jsonp,cors)

[复制链接]
  • TA的每日心情
    奋斗
    2024-11-24 15:47
  • 签到天数: 804 天

    [LV.10]以坛为家III

    2053

    主题

    2111

    帖子

    72万

    积分

    管理员

    Rank: 9Rank: 9Rank: 9

    积分
    726782
    发表于 2021-5-19 14:58:05 | 显示全部楼层 |阅读模式

    跨域

    跨域有三个条件,满足任何一个条件就是跨域
     1:服务器端口不一致
     2:协议不一致
     3:域名不一致

    解决方案:

    1.jsonp

      在远程服务器上设法动态的把数据装进js格式的文本代码段中,供客户端调用和进一步处理;在前台通过动态添加script标签及src属性,表面看上去与ajax极为相似,但是,这和ajax并没有任何关系;为了便于使用及交流,逐渐形成了一中非正式传输协议,人们把它称作 jsonp

    代码如下:

    html:

    < body >
    < form action= "/" method= "post" enctype= "multipart/form-data" >
    < input type= "text" name= "xinxi" id= "info" >< br >
    < input type= "file" name= "file" id= "file" >< br >
    < input type= "button" value= "提交" name= "submit" id= "btn" >
    </ form >
    </ body >
    < script src= "./jquery.js" > < / script >
    < script >
    //提前写好函数,调用函数需要传参
    function callback( data){
    alert( data);
    }
    //动态添加script标签及src属性
    $( '#btn'). on( 'click', function(){
    var sc = document. createElement( 'script');
    sc. src = 'http://soul:8888/kuayu?cb=callback';
    $( 'head'). append( sc);
    })
    < / script >   

    js:

     

     1 var http = require('http');
     2 var url = require('url');
     3 var server = http.createServer();
     4 server.listen('8888',function(){
     5     console.log('8888');
     6 });
     7 server.on('request',function(req,res){
     8     var urls = url.parse(req.url,true);
     9     if(urls.pathname == '/kuayu'){
    10         res.end('callback("jsonp")');//返回的数据需是前端定义的函数调用的形式
    11     }
    12 });

     运行结果:

     

     

     总结一下:

      jsonp的一个要点就是允许用户传递一个callback参数给服务端, 然后服务端返回数据时会将这个callback参数作为函数名来包裹住JSON数据, 这样客户端就可以随意定制自己的函数来自动处理返回数据了。

      发现凡是拥有"src"这个属性的标签都拥有跨域的能力,比如script、img、iframe; src 的能力就是把远程的数据资源加载到本地(图片、JS代码等);

     

    2.cors

    cors跨域的核心点是在服务端代码中设置一个响应头即可

    res.setHeader('Access-Control-Allow-Origin','*');

     html:

    <body>
        <form action="/" method="post" enctype="multipart/form-data" id="form">
            <input type="text" name="xinxi" id="info"><br>
            <input type="button" value="提交" name="submit" id="btn">
        </form>
    </body>
    <script src="./jquery.js"></script>
    <script>
        $('#btn').on('click', function () {           
                    $.ajax({
                            url: 'http://soul:8888/kuayu',
                            type:'delete',   
                            async:false,
                            success: function (data) {
                                alert(data);
                            },
                    })
        })
    </script>

     

    js代码:

    var http = require('http');
    var url = require('url');
    var server = http.createServer();
    server.listen('8888',function(){
        console.log('8888');
    });
    server.on('request',function(req,res){

        // 允许所有请求域
        // res.setHeader('Access-Control-Allow-Origin','*');
        // 只允许具体的一个域进行数据共享
        // res.setHeader('Access-Control-Allow-Origin','http://127.0.0.1:8000');

       var urls = url.parse(req.url,true);
        res.setHeader('Access-Control-Allow-Origin','*');
        if(req.method == 'POST' || req.method == 'GET'){
            if(urls.pathname == '/kuayu'){
                res.end('hello,world');
            }
        // 客户端发送预先检查请求,响应会客户端, }
    else if(req.method == 'OPTIONS'){ res.setHeader('Access-Control-Allow-Methods', 'DELETE');//设置所允许的真是请求(delete,put等) res.end('');
      // 客户端发送真实请求,响应数据 }
    else if(req.method == 'DELETE'){ res.end('Bye'); } });

     

    效果:

     

     

     

       很多人也认为使用CORS解决跨域很简单,只需要在服务器添加响应头 “ Access-Control-Allow-Origin :* ” 就可以了,

    其实不然,因为在CORS中,所有的跨域请求被分为了两种类型,一种是简单请求,一种是复杂请求 (严格来说应该叫‘需预检请求’);简单请求与普通的ajax请求无异;但复杂请求,必须在正式发送请求前先发送一个OPTIONS方法的请求已得到服务器的同意,若没有得到服务器的同意,浏览器不会发送正式请求;

    满足以下所有条件,被视为简单类型的请求:

    1:请求方法必须是 GET、HEAD、POST中的一种,其他方法不行;

    2:请求头类型只能是 Accept、Accept-Language、Content-Language、Content-Type,添加其他额外请求头不行;

    3:请求头 Content-Type 如果有,值只能是 text/plain、multipart/form-data、application/x-www-form-urlencoded 中的一种,其他值不行;

    4:请求中的任意 XMLHttpRequestUpload  对象均没有注册任何事件监听器;

    5:请求中没有使用 ReadableStream 对象。(以上摘自西岭老湿微信公众号)

     

    总结一下:

    如果请求方式为get和post简单请求,则只需要设置响应头:res.setHeader('Access-Control-Allow-Origin','*');来允许某一个域 或者 所有域进行数据共享;

    若是其他方式的请求,会在发送真正的请求之前发送一个options请求,通过options请求里设置:res.setHeader('Access-Control-Allow-Methods', 'DELETE'),

    告知服务器正式请求会使用哪一种 HTTP 请求方法。

     

     

     

     

    哎...今天够累的,签到来了1...
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|手机版|小黑屋|Java自学者论坛 ( 声明:本站文章及资料整理自互联网,用于Java自学者交流学习使用,对资料版权不负任何法律责任,若有侵权请及时联系客服屏蔽删除 )

    GMT+8, 2025-1-23 12:07 , Processed in 0.060493 second(s), 28 queries .

    Powered by Discuz! X3.4

    Copyright © 2001-2021, Tencent Cloud.

    快速回复 返回顶部 返回列表