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入门到精通教程
查看: 443|回复: 0

利用servlet做转发,实现js跨域解决同源问题

[复制链接]
  • TA的每日心情
    奋斗
    4 天前
  • 签到天数: 802 天

    [LV.10]以坛为家III

    2053

    主题

    2111

    帖子

    72万

    积分

    管理员

    Rank: 9Rank: 9Rank: 9

    积分
    726006
    发表于 2021-6-8 12:19:37 | 显示全部楼层 |阅读模式

        做前端开发,避免不了跨域这个问题,跨域具体什么概念,不赘述,博客里太多。简单说下,我们用js发请求,不管post还是get,如果发请求的对象和当前web页面不在同一域名下,浏览器的同源策略会限制发请求,也就是说,如果单独写个HTML,用js发远程请求,是发布出去的,浏览器会认为这是不安全的,js在这里能做的很有限。

        网上看了很多文章,小弟愚钝,只用js一直没解决这个问题,jQuery的Ajax据说可以,但是测试后发现不行,也许是浏览器版本的原因。有种方法是jsonp,但是好像需要服务器支持,我对服务器端程序了解的少,不懂。再就是script,动态的添加script标签,在src里面填要发的请求地址,但是很明显,只能以get方式发请求,那么post怎么办?反正折磨了很有一段时间,狠下心来,不用js去处理了,用java代码做中转,学过一点皮毛,参考一下网上代码,问题得以解决。

        其实分析起来问题很简单,servlet不难,tomcat去处理,很多细节我们不用关心,再就是用java发请求了,之前一直找错方向饶了不少弯路。

     

    首先写个java类,处理get和post请求

    参考这篇文章http://www.cnblogs.com/zhuawang/archive/2012/12/08/2809380.html,注释写得比较详细,我就简单剽窃一下吧相爱

    package web;
    //注意打包的地方,因为后面servlet会用到
    import java.io.BufferedReader;
    import java.io.IOException;
    import java.io.InputStreamReader;     
    import java.io.PrintWriter;
    import java.net.URL;
    import java.net.URLConnection;
    import java.util.List;
    import java.util.Map;
    
    public class SendPack {
        //发送get请求    url?a=x&b=xx形式
        public static String sendGet(String url,String param){
            String result = "";
            BufferedReader in = null;
            try{
                String urlName = "";
                if(param.length() != 0){
                    urlName = url + "?" +param;
                }
                else urlName = url;
                URL resUrl = new URL(urlName);
                URLConnection urlConnec = resUrl.openConnection();
                urlConnec.setRequestProperty("accept", "*/*");
                urlConnec.setRequestProperty("connection", "Keep-Alive");
                urlConnec.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
                urlConnec.connect();
                Map<String, List<String>> map = urlConnec.getHeaderFields();
                for (String key : map.keySet()) {
                    System.out.println(key + "--->" + map.get(key));
                }
                 // 定义 BufferedReader输入流来读取URL的响应
                in = new BufferedReader(new InputStreamReader(urlConnec.getInputStream()));
                String line;
                while ((line = in.readLine()) != null) {
                    result += line;
                }
            }catch(Exception e){
                System.out.println("发送get请求失败"+e);
                e.printStackTrace();
            }finally{
                try{
                    if(in != null){
                        in.close();
                    }
                }catch(Exception e){
                    e.printStackTrace();
                }
            }
            return result;
        }
        //发送post请求
        public static String sendPost(String url,String param){
            String result = "";
            PrintWriter out = null;
            BufferedReader in = null;
            try{
                URL resUrl = new URL(url);
                URLConnection urlConnec = resUrl.openConnection();
                urlConnec.setRequestProperty("accept", "*/*");
                urlConnec.setRequestProperty("connection", "Keep-Alive");
                urlConnec.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
                // 发送POST请求必须设置如下两行
                urlConnec.setDoInput(true);
                urlConnec.setDoOutput(true);
                
                out = new PrintWriter(urlConnec.getOutputStream());
                out.print(param);//发送post参数
                out.flush();
                 // 定义 BufferedReader输入流来读取URL的响应
                in = new BufferedReader(new InputStreamReader(urlConnec.getInputStream()));
                String line;
                while ((line = in.readLine()) != null) {
                    result += line;
                }
            }catch(Exception e){
                System.out.println("post请求发送失败"+e);
                e.printStackTrace();
            }finally{
                try{
                    if(in != null){
                        in.close();
                    }
                    if(out != null){
                        out.close();
                    }
                }catch(Exception e){
                    e.printStackTrace();
                }
            }
            return result;
        }
        /**测试
         * 说明:这里用新浪股票接口做get测试,新浪股票接口不支持jsonp,至于post,因为本人用的公司的接口就不展示了,一样的,一个url,一个数据包
         */
        /*
        public static void main(String[] args) {
            // TODO Auto-generated method stub
            String resultGet = sendGet("http://hq.sinajs.cn/list=sh600389","");
            System.out.println(resultGet);
        }
        */
        
    }

    然后是servlet程序,写servlet需要一点基础知识

    本人用Eclipse开发,没有正式写J2ee,暂时不管了,不偷懒的好处是流程可以学得更清楚,好了。

    注意一点,建的工程,要写servlet要导包

    image_thumb,右键工程,Build Path—>Add External Archives会弹出文件浏览器,选择要添加的额外的包

     

    去自己的tomcat目录下面找

    image_thumb11,servlet-api.jar包,包含进来。

    好了,接下来是servlet代码

    package web;
    //注意打包的地方,因为后面servlet会用到
    import java.io.IOException;
    import java.io.PrintWriter;
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import web.SendPack;
    
    public class ForwardRequest extends HttpServlet{
    
        public void doGet(HttpServletRequest req,HttpServletResponse res) throws ServletException{
            res.setCharacterEncoding("utf-8");
            String addr=req.getParameter("address");//前端规定送的url地址,不懂就去了解一下json
            String param=req.getParameter("param");    //同上,传的参数,字符串类型(不管什么格式,字符串传了再说,指定啥格式,前端再解析)    
            try {
                PrintWriter pw = res.getWriter();
                String result = SendPack.sendGet(addr, param);//get请求
                  pw.print(result);//把数据返回给前端
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        public void doPost(HttpServletRequest req,HttpServletResponse res) throws ServletException{
            res.setCharacterEncoding("utf-8");
            String addr=req.getParameter("address");
            String param=req.getParameter("param");    
            try {
                PrintWriter pw = res.getWriter();
                String result = SendPack.sendPost(addr, param);//post请求
                  pw.print(result);//把数据返回给前端
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            
        }
    }

    好了,现在编译下,找到class文件,编译我就不说了,

    image_thumb2,class文件上级目录web,将web文件夹复制,粘到哪里呢,先等等。

    先要部署tomcat,在tomcat的webapps目录下面新建一个文件夹testsendpack。里面添加子文件夹WEB-INF,然后再WEB-INF目录下添加classes目录,将刚要粘贴的web文件夹粘贴到这里。在classes文件夹同目录下新建一个web.xml配置文件。

    image_thumb3

    web.xml内容如下(可以直接去root目录或其他目录找,这里我就把自带的注释删掉)

    <?xml version="1.0" encoding="ISO-8859-1"?>
    <web-app xmlns="http://java.sun.com/xml/ns/javaee"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
                          http://java.sun.com/xml/ns/javaee/web-app_3_1.xsd"
      version="3.1"
      metadata-complete="true">
    
      <display-name>servlet ajax</display-name>
      <description>
         servlet ajax
      </description>
    
      <servlet>
        <servlet-name>ajaxreq</servlet-name><!--给自己的servlet取个名字-->
        <servlet-class>web.ForwardRequest</servlet-class><!--这里就是servlet代码里强调的包问题,就是servlet的class文件但没有后缀-->
      </servlet>
      <servlet-mapping>
        <servlet-name>ajaxreq</servlet-name><!--这里要注意跟上面取的servlet名字一致-->
        <url-pattern>/forwardreq</url-pattern>
        <!--这里是设置servlet的url路径,在用js发送请求时url就是webapps下的建的文件夹名加上这个,这里是testsendpack/forwardreq -->
      </servlet-mapping>
    </web-app>

    好了,环境已经搭好了,让我们来做测试吧

    我们在testsendpack目录下面新建一个html文件,名字自己去取啦,我取index,这里我就偷个懒,就jq发Ajax请求,方便点。

    <!DOCTYPE html>
    <html>
        <head>
            <meta charset="utf-8">    
            <title>ajax发请求servlet处理</title>
            <script type="text/javascript" src="jquery-1.8.2.js"></script>
        </head>
        <body>
            <button id='btnget'>get</button>
            <button id='btnpost'>post</button>
            <script type="text/javascript">
                function sendPack(sendType,url,para,asyn){
                    /*
                     * 参数依次为发送类型,post还是get,url地址,参数,是否异步,默认异步
                       */
                    if(asyn == undefined) asyn = true;
                    $.ajax({
                        url:"/testsendpack/forwardreq",//servlet地址
                           type: sendType,
                        contentType: 'application/x-www-form-urlencoded; charset=UTF-8',
                        dataType:"text",
                        data:{
                            address:url,
                            param : para
                        },
                        async : asyn,
                        success:function (data){
                            alert(data);
                        },
                        error: function(xhr, state, err) {
                            alert('与后台通信失败。故障信息:' + err);
                        }
                    });
                }
                $(function(){
                    $("#btnget").click(function(){
                        sendPack("GET","http://hq.sinajs.cn/list=sh600389","");
                    });
                    $("#btnpost").click(function(){
                        //sendPack();
                    });
                });
            </script>
        </body>
    </html>

    因为post的例子是公司的,不好放出来,哪位仁兄知道有公共的post例子可以提供下,经测试post是没有问题的,如果有问题,留言问我。

    开启tomcat,bin目录下的startup.bat,弹出的黑框,可以看到servlet被加载没有,如果你看到testsendpack并且没有一大坨乱七八糟的东西,那么恭喜,离成功仅一步之遥。如果你出现黑框一闪即逝,不要慌,用记事本打开startup.bat,在最后一行加上pause,好了,在跑一下,你可以看到什么错误信息,八成是jre环境没找到吧,配java环境简单说下,找到jdk目录,复制路径,系统环境变量里新建JAVA_HOME,粘上路径,然后在path的最后面加上;%JAVA_HOME%bin就可以了。

     

    最后运行一下吧,浏览器里输入127.0.0.1:8080/testsendpack/index.html,

    附上结果image_thumb1,好了,江山股份的行情查到了,字段啥意思,不想研究了,get请求和post请求的转发都实现了,post不写例子不要怪我,我找不着。。。

    返回的字符串,想怎么处理就怎么处理吧。

    最后最后,有啥问题可以给我留言,欢迎吐槽相爱

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

    使用道具 举报

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

    本版积分规则

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

    GMT+8, 2024-11-15 07:51 , Processed in 0.059486 second(s), 28 queries .

    Powered by Discuz! X3.4

    Copyright © 2001-2021, Tencent Cloud.

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