当前位置: 首页 > news >正文

使用Httpclient来替代客户端的jsonp跨域解决方案

最近接手一个项目,新项目需要调用老项目的接口,但是老项目和新项目不再同一个域名下,所以必须进行跨域调用了,但是老项目又不能进行任何修改,所以jsonp也无法解决了,于是想到了使用了Httpclient来进行服务端的“跨域”来替代jsonp的客户端跨域方案。

上一篇博文中,详细剖析了jsonp的跨域原理,本文使用Httpclient来替代jsonp的客户端跨域方案。

先去 http://hc.apache.org/downloads.cgi 下载最新版httpclient。解压tutorial文件夹中有html和PDF的使用介绍。

下面实现从8888端口的html4项目中跨域访问8080端口的html5项目中的JsonServlet:

1)在html4中建立一个中间代理servelt和一个工具类,工具类代码如下:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

import java.io.IOException;

import java.io.OutputStream;

import org.apache.http.HttpEntity;

import org.apache.http.StatusLine;

import org.apache.http.client.ClientProtocolException;

import org.apache.http.client.HttpResponseException;

import org.apache.http.client.methods.CloseableHttpResponse;

import org.apache.http.client.methods.HttpPost;

import org.apache.http.impl.client.CloseableHttpClient;

import org.apache.http.impl.client.HttpClients;

public class HttpUtil

{

    public static boolean returnResponseOfUrl(String url, OutputStream os)

    {

        CloseableHttpClient httpclient = HttpClients.createDefault();

        HttpPost httpPost = new HttpPost(url);

        CloseableHttpResponse response = null;

        try{

            response = httpclient.execute(httpPost);

             

            StatusLine statusLine = response.getStatusLine();

            HttpEntity entity = response.getEntity();

            if(statusLine != null && statusLine.getStatusCode() >= 300){

                throw new HttpResponseException(statusLine.getStatusCode(),

                                                statusLine.getReasonPhrase());

            }

            if(entity == null){

                throw new ClientProtocolException("response contains no content");

            }

             

            entity.writeTo(os);

            return true;

        }catch(IOException e){

            e.printStackTrace();

            return false;

        }finally{

            if(response != null){

                try{

                    response.close();

                }catch(IOException e){

                    e.printStackTrace();

                }

            }

        }

    }

}

 中间代理servlet代码如下:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

@WebServlet("/HttpclientServlet")

public class HttpclientServlet extends HttpServlet

{

    private static final long serialVersionUID = 1L;

        

    public HttpclientServlet()

    {

        super();

    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException

    {

        this.doPost(request, response);

    }

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException

    {

        String url = request.getParameter("url");

        if(url != null){

            if(!HttpUtil.returnResponseOfUrl(url, response.getOutputStream())){

                if(!HttpUtil.returnResponseOfUrl(url, response.getOutputStream())){ // 如果出错,再试一次

                    // log.error("url:" + url);

                }; 

            }

        }

    }

}

 html4项目中的访问页面代码如下:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

<!doctype html>

<html>

<head>

    <meta charset="utf-8">

    <meta name="keywords" content="jsonp">

    <meta name="description" content="jsonp">

    <title>jsonp</title>

    <style type="text/css">

        *{margin:0;padding:0;}

        div{width:600px;height:100px;margin:20px auto;}

    </style>

</head>

<body>

    <div>

        <a href="javascript:;">jsonp测试</a>

    </div>

     

<script type="text/javascript" src="js/jquery-1.11.1.js"></script>

<script type="text/javascript">

$(function(){

    $("a").on("click", function(){     

        $.ajax({

            type:"post",

            url:"http://localhost:8888/html4/HttpclientServlet?url="+ecodeURIComponent("http://localhost:8080/html5/JsonServlet"),

            success:function(data) {

                console.log(data);

                console.log(data.name);

                console.log(data.age);

                var user = JSON.parse(data);

                console.log(user.name);

                console.log(user.age);

            }

        });

    })

});

</script>

</body>

</html>

上面通过:url=http://localhost:8080/html5/JsonServlet 将我们最终要跨域访问的url地址传给自己服务器下的 HttpclientServlet. 然后在 HttpclientServlet 中使用httpclient访问 跨域 url  中的servlet,成功之后,将返回的结果返回给客户端

html5项目中被 跨域 访问的servlet代码如下:

@WebServlet("/JsonServlet")
public class JsonServlet extends HttpServlet 
{private static final long serialVersionUID = 4335775212856826743L;protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {User user = new User();user.setName("yuanfang");user.setAge(100);Object obj = JSON.toJSON(user);System.out.println(user);            // com.tz.servlet.User@164ff87System.out.println(obj);            // {"age":100,"name":"yuanfang"}response.getWriter().println(obj);}protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {this.doPost(request, response);}
}

启动8888和8080端口的tomcat,访问 http://localhost:8888/html4/jsonp.html ,结果如下:

我们注意到第二和第三项都打印的是 undefined ,这是因为 中间代理的 HttpclientServlet,使用的是直接输出流的方式,所以最终返回的结果不是Json对象,而是字符串,所以需要使用 var user = JSON.parse(data); 来进行解析成 javascript对象就可以,所以第四和第五项都正常输出了结果。

如果想返回的是json对象,加一句代码 response.setContentType("text/json;charset=utf-8"); 就可以:

1

2

3

4

5

6

7

8

if(url != null){

    response.setContentType("text/json;charset=utf-8");

    if(!HttpUtil.returnResponseOfUrl(url, response.getOutputStream())){

    if(!HttpUtil.returnResponseOfUrl(url, response.getOutputStream())){ // 如果出错,再试一次

        // log.error("url:" + url);

        }; 

    }

}   

这样的话,浏览器在看到 contentType: "text/json;charset=utf-8" 时,它的js执行引擎会自动帮助我们将字符串解析成json对象。也就是相当于自动调用了 JSON.parse(data) 的效果

相关文章:

使用Httpclient来替代客户端的jsonp跨域解决方案

最近接手一个项目&#xff0c;新项目需要调用老项目的接口&#xff0c;但是老项目和新项目不再同一个域名下&#xff0c;所以必须进行跨域调用了&#xff0c;但是老项目又不能进行任何修改&#xff0c;所以jsonp也无法解决了&#xff0c;于是想到了使用了Httpclient来进行服务端…...

测试工具Jmeter:设置中文界面

首先我们打开Jmeter所在的文件&#xff0c;进入bin目录&#xff0c;打开Jmeter.properties&#xff1a; 打开后找到languageen&#xff1a; 改为zh_CN: 保存关闭&#xff0c;然后再打开Jmeter&#xff1a; 英文并不会显得高级&#xff0c;能做到高效的性能测试才是高级的。...

K8s攻击案例:RBAC配置不当导致集群接管

01、概述 Service Account本质是服务账号&#xff0c;是Pod连接K8s集群的凭证。在默认情况下&#xff0c;系统会为创建的Pod提供一个默认的Service Account&#xff0c;用户也可以自定义Service Account&#xff0c;与Service Account关联的凭证会自动挂载到Pod的文件系统中。 …...

运行hive的beelin2时候going to print operations logs printed operations logs

运行hive的beelin2时候going to print operations logs printed operations logs 检查HiveServer2的配置文件hive-site.xml&#xff0c;确保以下属性被正确设置&#xff1a; <property><name>hive.async.log.enabled</name><value>false</value>…...

从 MySQL 到 DolphinDB,Debezium + Kafka 数据同步实战

Debezium 是一个开源的分布式平台&#xff0c;用于实时捕获和发布数据库更改事件。它可以将关系型数据库&#xff08;如 MySQL、PostgreSQL、Oracle 等&#xff09;的变更事件转化为可观察的流数据&#xff0c;以供其他应用程序实时消费和处理。本文中我们将采用 Debezium 与 K…...

六.聚合函数

聚合函数 1.什么是聚合函数1.1AVG和SUM函数1.2MIN和MAX函数1.3COUNT函数 2.GROUP BY2.1基本使用2.2使用多个列分组2.3GROUP BY中使用WITH ROLLUP 3.HAVING3.1基本使用3.2WHERE和HAVING的区别 4.SELECT的执行过程4.1查询的结构4.2SELECT执行顺序4.3SQL执行原理 1.什么是聚合函数…...

Eclipse_03_如何加快index速度

1. ini配置文件 -Xms&#xff1a;是最小堆内存大小&#xff0c;也是初始堆内存大小&#xff0c;因为堆内存大小可以根据使用情况进行扩容&#xff0c;所以初始值最小&#xff0c;随着扩容慢慢变大。 -Xmx&#xff1a;是最大堆内存大小&#xff0c;随着堆内存的使用率越来越高&a…...

scrapy的入门和使用

scrapy的入门使用 学习目标&#xff1a; 掌握 scrapy的安装应用 创建scrapy的项目应用 创建scrapy爬虫应用 运行scrapy爬虫应用 scrapy定位以及提取数据或属性值的方法掌握 response响应对象的常用属性 1 安装scrapy 命令:     sudo apt-get install scrapy 或者&#x…...

yolov5单目测距+速度测量+目标跟踪(算法介绍和代码)

要在YOLOv5中添加测距和测速功能&#xff0c;您需要了解以下两个部分的原理&#xff1a; 单目测距算法 单目测距是使用单个摄像头来估计场景中物体的距离。常见的单目测距算法包括基于视差的方法&#xff08;如立体匹配&#xff09;和基于深度学习的方法&#xff08;如神经网…...

flink 读取 apache paimon表,查看source的延迟时间 消费堆积情况

paimon source查看消费的数据延迟了多久 如果没有延迟 则显示0 官方文档 Metrics | Apache Paimon...

无人机在融合通信系统中的应用

无人驾驶飞机简称“无人机”&#xff0c;是利用无线电遥控设备和自备的程序控制装置操纵的不载人飞行器&#xff0c;现今无人机在航拍、农业、快递运输、测绘、新闻报道多个领域中都有深度的应用。 在通信行业中&#xff0c;无人机广泛应用于交通&#xff0c;救援&#xff0c;消…...

MySQL库的操作

目录 创建数据库创建数据库案例字符集和校验规则查看系统默认字符集以及校验规则查看数据库支持的字符集查看数据库支持的字符集校验规则校验规则对数据库的影响 操纵数据库查看数据库修改数据库删除数据库数据库备份和恢复表的备份和恢复查看连接情况 创建数据库 创建数据库的…...

服务器解析漏洞有哪些?IIS\APACHE\NGINX解析漏洞利用

解析漏洞是指在Web服务器处理用户请求时&#xff0c;对输入数据&#xff08;如文件名、参数等&#xff09;进行解析时产生的漏洞。这种漏洞可能导致服务器对用户提供的数据进行错误解析&#xff0c;使攻击者能够执行未经授权的操作。解析漏洞通常涉及到对用户输入的信任不足&am…...

Https图片链接下载问题

1. 获取方法 入参是一个Url, 和一个随机的名称. 返回值是MultipartFile, 这里因为我这里需要调接口传到服务器, 这里也可以直接通过inputStream进行操作. 按需修改 /*** 通过Url获取文件** param url* param fileName 随机产生一个文件名, 可以是uuid等* return* throws Excep…...

Wireshark在移动网络中的应用

第一章&#xff1a;Wireshark基础及捕获技巧 1.1 Wireshark基础知识回顾 1.2 高级捕获技巧&#xff1a;过滤器和捕获选项 1.3 Wireshark与其他抓包工具的比较 第二章&#xff1a;网络协议分析 2.1 网络协议分析&#xff1a;TCP、UDP、ICMP等 2.2 高级协议分析&#xff1a;HTTP…...

Leetcode 1901. 寻找峰值 II(Java + 列最大值 + 二分)

题目 1901. 寻找峰值 II 一个 2D 网格中的 峰值 是指那些 严格大于 其相邻格子(上、下、左、右)的元给你一个 从 0 开始编号 的 m x n 矩阵 mat &#xff0c;其中任意两个相邻格子的值都 不相同 。找出 任意一个 峰值 mat[i][j] 并 返回其位置 [i,j] 。你可以假设整个矩阵周边…...

RabbitMQ 消息持久化

默认情况下&#xff0c;exchange、queue、message 等数据都是存储在内存中的&#xff0c;这意味着如果 RabbitMQ 重启、关闭、宕机时所有的信息都将丢失。 RabbitMQ 提供了持久化来解决这个问题&#xff0c;持久化后&#xff0c;如果 RabbitMQ 发送 重启、关闭、宕机&#xff…...

Opencv实验合集——实验四:图片融合

1.概念 图像融合是将两个或多个图像结合在一起&#xff0c;创建一个新的图像的过程。这个过程的目标通常是通过合并图像的信息来获得比单个图像更全面、更有信息量的结果。图像融合可以在许多领域中应用&#xff0c;包括计算机视觉、遥感、医学图像处理等。 融合的方法有很多…...

Java复习

CH1 Java Fundamentals 1.1 Java Features&#xff08;java特色&#xff09; 1.1 Simplicity: simple grammar, rich library 简单好用&#xff1a; 语法简单&#xff0c;库文件丰富 1.2 Pure OO: everything is object! 所有程序都是对象 1.3 Security: memory access,…...

腾讯云微服务11月产品月报 | TSE 云原生 API 网关支持 WAF 对象接入

2023年 11月动态 TSE 云原生 API 网关 1、支持使用私有 DNS 解析 服务来源支持私有 DNS 解析器&#xff0c;用户可以添加自己的 DNS 解析器地址进行私有域名解析&#xff0c;适用于服务配置了私有域名的用户。 2、支持 WAF 对象接入 云原生 API 网关对接 Web 安全防火墙&…...

[特殊字符] 智能合约中的数据是如何在区块链中保持一致的?

&#x1f9e0; 智能合约中的数据是如何在区块链中保持一致的&#xff1f; 为什么所有区块链节点都能得出相同结果&#xff1f;合约调用这么复杂&#xff0c;状态真能保持一致吗&#xff1f;本篇带你从底层视角理解“状态一致性”的真相。 一、智能合约的数据存储在哪里&#xf…...

树莓派超全系列教程文档--(61)树莓派摄像头高级使用方法

树莓派摄像头高级使用方法 配置通过调谐文件来调整相机行为 使用多个摄像头安装 libcam 和 rpicam-apps依赖关系开发包 文章来源&#xff1a; http://raspberry.dns8844.cn/documentation 原文网址 配置 大多数用例自动工作&#xff0c;无需更改相机配置。但是&#xff0c;一…...

MFC内存泄露

1、泄露代码示例 void X::SetApplicationBtn() {CMFCRibbonApplicationButton* pBtn GetApplicationButton();// 获取 Ribbon Bar 指针// 创建自定义按钮CCustomRibbonAppButton* pCustomButton new CCustomRibbonAppButton();pCustomButton->SetImage(IDB_BITMAP_Jdp26)…...

如何在看板中体现优先级变化

在看板中有效体现优先级变化的关键措施包括&#xff1a;采用颜色或标签标识优先级、设置任务排序规则、使用独立的优先级列或泳道、结合自动化规则同步优先级变化、建立定期的优先级审查流程。其中&#xff0c;设置任务排序规则尤其重要&#xff0c;因为它让看板视觉上直观地体…...

uni-app学习笔记二十二---使用vite.config.js全局导入常用依赖

在前面的练习中&#xff0c;每个页面需要使用ref&#xff0c;onShow等生命周期钩子函数时都需要像下面这样导入 import {onMounted, ref} from "vue" 如果不想每个页面都导入&#xff0c;需要使用node.js命令npm安装unplugin-auto-import npm install unplugin-au…...

java调用dll出现unsatisfiedLinkError以及JNA和JNI的区别

UnsatisfiedLinkError 在对接硬件设备中&#xff0c;我们会遇到使用 java 调用 dll文件 的情况&#xff0c;此时大概率出现UnsatisfiedLinkError链接错误&#xff0c;原因可能有如下几种 类名错误包名错误方法名参数错误使用 JNI 协议调用&#xff0c;结果 dll 未实现 JNI 协…...

【Redis技术进阶之路】「原理分析系列开篇」分析客户端和服务端网络诵信交互实现(服务端执行命令请求的过程 - 初始化服务器)

服务端执行命令请求的过程 【专栏简介】【技术大纲】【专栏目标】【目标人群】1. Redis爱好者与社区成员2. 后端开发和系统架构师3. 计算机专业的本科生及研究生 初始化服务器1. 初始化服务器状态结构初始化RedisServer变量 2. 加载相关系统配置和用户配置参数定制化配置参数案…...

srs linux

下载编译运行 git clone https:///ossrs/srs.git ./configure --h265on make 编译完成后即可启动SRS # 启动 ./objs/srs -c conf/srs.conf # 查看日志 tail -n 30 -f ./objs/srs.log 开放端口 默认RTMP接收推流端口是1935&#xff0c;SRS管理页面端口是8080&#xff0c;可…...

NPOI Excel用OLE对象的形式插入文件附件以及插入图片

static void Main(string[] args) {XlsWithObjData();Console.WriteLine("输出完成"); }static void XlsWithObjData() {// 创建工作簿和单元格,只有HSSFWorkbook,XSSFWorkbook不可以HSSFWorkbook workbook new HSSFWorkbook();HSSFSheet sheet (HSSFSheet)workboo…...

MacOS下Homebrew国内镜像加速指南(2025最新国内镜像加速)

macos brew国内镜像加速方法 brew install 加速formula.jws.json下载慢加速 &#x1f37a; 最新版brew安装慢到怀疑人生&#xff1f;别怕&#xff0c;教你轻松起飞&#xff01; 最近Homebrew更新至最新版&#xff0c;每次执行 brew 命令时都会自动从官方地址 https://formulae.…...