夸克文库智搜
夸克文库智搜API是一款专业的文档搜索代理接口,通过智能HTML解析技术自动提取夸克文档搜索结果。接口支持GET/POST多种请求方式,返回包含标题、页数、大小、热度、缩略图等完整信息的结构化JSON数据。采用优雅降级设计,即使解析失败也能给出友好提示。让您轻松集成夸克文档搜索功能到自己的应用中!
计费优先级(按已开通的计费类型依次校验):
全站会员->单独包月->次数包->点数计费->账户余额->免费额度
账户余额:
该产品支持账户余额抵扣,每次扣除金额:0.005 元/次
全站会员:
全站会员有效期内,可免费使用本产品。
包年包月:
| 包月价格 | 包季价格 | 包年价格 |
|---|---|---|
| ¥ 50.00 约 1.61 元/天 | ¥ 120.00 约 1.33 元/天 | ¥ 360.00 约 0.98 元/天 |
次数包:
| 额度 | 价格 | 有效期 |
|---|---|---|
| 10000 (次) | ¥ 30 低至0.003/次 | 一年 |
| 100000 (次) | ¥ 268 低至0.00268/次 | 一年 |
| 1000000 (次) | ¥ 2180 低至0.00218/次 | 一年 |
免费额度:
| 总免费额度 | 每月免费额度 | 每日免费额度 |
|---|---|---|
| 4000 (次) | 400 (次) 包含在总免费额度 | 20 (次) 包含在总免费额度 |
请求限制:
| 免费/测试用户请求频率限制 | 请求频率总限制 | 全站会员请求频率限制 | 每日请求次数总限制 |
|---|---|---|---|
| 5秒1次 每个免费用户的QPS总限制 | 1秒10次 每个用户QPS总限制 | 1秒10次 每个全站会员用户的QPS总限制 | 100000 (次) 每个用户每日请求总次数 |
其他准入要求:
接口地址: https://www.ninyao.cn/api/kkzs/index
返回格式: application/json
请求方式: HTTPGET
请求HEADER:
| 名称 | 值 |
|---|---|
| Content-Type | application/x-www-form-urlencoded 或 application/json |
请求参数说明:
| 名称 | 必填 | 类型 | 示例值 | 说明 |
|---|---|---|---|---|
| q | 是 | string | 人工智能 | 搜索关键词,长度1-200字符 |
返回参数说明:
| 名称 | 类型 | 说明 |
|---|---|---|
| code | int | 状态码:200成功,400参数错误,500服务器错误 |
| message | string | 状态描述信息 |
| data | object | 搜索结果数据,包含keyword、total、documents字段 |
| data.keyword | string | 搜索关键词 |
| data.total | int | 搜索结果总数 |
| data.documents | array | 文档列表数组,每个文档包含以下字段 |
| documents[].docId | string | 文档唯一标识 |
| documents[].title | string | 文档标题(已清理HTML标签) |
| documents[].pageNum | int | 文档页数 |
| documents[].size | string | 文档大小(如:17.5KB、1.4M) |
| documents[].hot | string | 文档热度/浏览量 |
| documents[].fileFormat | string | 文件格式(docx、pdf、pptx、txt等) |
| documents[].thumbnail | string | 文档缩略图URL地址 |
| documents[].summary | string | 文档摘要(最多200字符) |
| documents[].docCategory | string | 文档分类(如:教育考试_笔记_大学) |
| tip | string | 接口提示信息 |
免责声明:
本服务仅供个人学习、学术研究目的使用,未经授权,请勿分享、传播输入及生成的文本、图片内容。用户在从事与本服务相关的一切行为(包括但不限于访问浏览、利用、转载、宣传介绍)时,应以善意且谨慎的态度行事并承担相应的风险和责任。用户需确保不得利用本服务进行危害国家安全和社会公共利益、扰乱经济秩序和社会秩序、侵犯他人合法权益等法律、行政法规禁止的活动,并且自定义输入文本不得包含违反法律法规、政治相关、侵犯他人合法权益的内容。对于用户因使用本服务而导致的任何损失或风险,包括但不限于由于使用本服务而产生的错误、疏忽、中断、删除、故障、延迟或通讯线路故障所导致的任何损失或损害,本服务的开发者将不承担任何责任。
请求示例:
https://www.ninyao.cn/api/kkzs/index?key=你的key&q=看文档返回示例:
{}
- "code": 200,
- "message": "搜索成功",
-"data": {},
- "keyword": "易语言",
- "total": 10,
-"documents": []
-{},
- "docId": "5BE5ADD0737E54A3E5736483F9DCA6B9",
- "title": "易语言简介和知识点",
- "pageNum": 5,
- "size": "17.5KB",
- "hot": "2",
- "fileFormat": "docx",
- "thumbnail": "http://s2.zimgs.cn/ims?kt=MD5&at=document&tv=0_0&sign=yx:MvtBpcH8NZ5hI_hZ1ucrI1YDtWo=&key=953A16FDFC7702CACA64570EEB6BE464&x.jpg",
- "summary": "简介易语言(EPL)是一门以中文作为程序代码编程语言,其以“易”著称,创始人为吴涛。易语言早期版本的名字为E语言,也通常代指与之对应的集成开发环境。其最早的版本的发布可追溯至2000年9月11日。创造易语言的初衷是进行用中文来编写程序的实践,方便中国人以中国人的思维编写程序,并不用再去学习西方思维。易语言的诞生极大的降低了编程的门槛和学习的难度。从2000年以来,易语言已经发展到一定的规模,功能上",
- "docCategory": "教育考试_笔记_大学"
-{},
- "docId": "44CE856E573738230045F7F568B87992",
- "title": "易语言相关资料",
- "pageNum": 11,
- "size": "140.8KB",
- "hot": "3",
- "fileFormat": "pptx",
- "thumbnail": "http://s2.zimgs.cn/ims?kt=MD5&at=document&tv=0_0&sign=yx:Jfod6z7svjNeIamrWaZqSx-6ynU=&key=A178E6A763EF2B4115EB574491F0F669&x.jpg",
- "summary": "认识“易语言”目前市场上的程序设计语言有:C、C++、C#、Java、Pascal、Visual Basic(VB)、易语言……易语言编写的程序:人为管制交通灯易语言编写的程序:比比谁胖谁瘦.e第1页/共10页第一页,共11页。“人为管制交通灯”程序在易语言中组件名在VB中组件名外形框1Shape1按钮1、按钮2、按钮3Command1、Command2、Command3第2页/共10页第二页,共",
- "docCategory": "行业资料_行业问答_其他问答"
-{},
- "docId": "83875C63A1E4044058FBFA027F359F75",
- "title": "易语言入门",
- "pageNum": 10,
- "size": "59KB",
- "hot": "2",
- "fileFormat": "doc",
- "thumbnail": "http://s2.zimgs.cn/ims?kt=MD5&at=document&tv=0_0&sign=yx:tQXV3uVaHRuXUX0mD3ROq6iQh3g=&key=1BC2239A4D0EC5025E507C39AC705681&x.jpg",
- "summary": "第一课.易语言的基本概念本节将向读者介绍什么是易语言,构成易语言程序有那些最基本的东西。正象盖房子一样,这里仅仅是准备钢筋,水泥,砖,瓦,沙,石等材料。同时在本章中我们还要介绍一些易语言常用的命令和常规的上机操作方法。 2.1易语言的特点 1.全可视化 一般的可视化编程语言,仅支持图形用户界面的可视化设计操作,而易语言除了支持此类可视化操作,还支持程序流程的即时可视化呈视,极大地减少了程序录入错误",
- "docCategory": "教育考试_教案_教案"
-{},
- "docId": "8C8DA1E745B1FE40ED8FC263C89D7CCE",
- "title": "易语言入门教程",
- "pageNum": 10,
- "size": "94KB",
- "hot": "1",
- "fileFormat": "pptx",
- "thumbnail": "http://s2.zimgs.cn/ims?kt=MD5&at=document&tv=0_0&sign=yx:gEV9vn1F3mgwsiAhjC-xH5LckWs=&key=12DFF05D57A4D778601D57E308550B95&x.jpg",
- "summary": "易语言入门教程会计学1认识“易语言”目前市场上的程序设计语言有:C、C++、C#、Java、Pascal、Visual Basic(VB)、易语言……第1页/共10页易语言编写的程序:人为管制交通灯“人为管制交通灯”程序在易语言中组件名在VB中组件名外形框1Shape1按钮1、按钮2、按钮3Command1、Command2、Command3第2页/共10页“人为管制交通灯” 程序填充红色功能",
- "docCategory": ""
-{},
- "docId": "E1AAD96F084C0F62B4CCB4F3DF9F2D50",
- "title": "易语言知识详解:基础概念与开发实践",
- "pageNum": 9,
- "size": "16.8KB",
- "hot": "1",
- "fileFormat": "docx",
- "thumbnail": "http://s2.zimgs.cn/ims?kt=MD5&at=document&tv=0_0&sign=yx:f7VVmRJmvNiPGHHiZhWwMwsShW4=&key=A9D0519E05DBC4EC654103D415D055D4&x.jpg",
- "summary": "易语言(EPL)是由中国软件工程师吴涛于2000年9月11日开发的一门以中文作为程序代码的编程语言 1 ,旨在让中文用户能够以母语思维进行软件开发,降低编程学习门槛。经过25年的发展,易语言已成为中文编程领域的重要代表,拥有自主知识产权的编译器和丰富的支持库 8 。它不仅支持Windows平台,还推出了面向专业开发者的"易语言.飞扬"版本,实现跨平台开发能力 8, 15 。本文将系统介绍易语言的基",
- "docCategory": ""
-{},
- "docId": "D7E58B99C958A668442FFF3ACB85EF4A",
- "title": "易语言第一课",
- "pageNum": 17,
- "size": "43.5KB",
- "hot": "9",
- "fileFormat": "doc",
- "thumbnail": "http://s2.zimgs.cn/ims?kt=MD5&at=document&tv=0_0&sign=yx:0lMwqoVqWiIvUQvz3Ccamuz5FD0=&key=B212C01093E609692C47D7BF0E3BB4B5&x.jpg",
- "summary": "第1章:“易语言”基础知识第一天今天我们先来学习一下有关“易语言”的一些基本知识,包括如何下载“易语言”如何安装“易语言”以及了解“易语言”的操作界面,最后我们将做一个小的易程序,来帮助大家初步了解编程。如何下载易语言?首先我们要在浏览器中输入” www.dywt.com.cn ”,进入到易语言的开始页中;点击“易语言”我们就可以进入到易语言网站的主页面中去;点击“免费下载”进入到易语言网站的下载",
- "docCategory": ""
-{},
- "docId": "22D47671FA91B30646F6F0F78BDF081A",
- "title": "易语言菜鸟教程合集【不完全版】",
- "pageNum": 85,
- "size": "473KB",
- "hot": "26",
- "fileFormat": "doc",
- "thumbnail": "http://s2.zimgs.cn/ims?kt=MD5&at=document&tv=0_0&sign=yx:6ptSr5ERfeL5pAyAnqHWODU6lWo=&key=ADAD47D6293B38F0C1768E9DADE9D452&x.jpg",
- "summary": "易语言常用语句(转载自.::Etp工作室::.之『教育部』) 对于初学者来说,即使代码是全中文的,也需要别人讲解才能明白其中的意思。如果我们能够理解其中大多数的代码的意思,那我们学习易语言就会相对容易。为此下面列举易语言常见的各类语句供大家学习或编程时参考。 ㈠、赋值型语句。(也可称属性型语句)(特征:有一个“=”号将左右两边连起来) 这是我们学易语言首先会接触的一类语句。比如:标签1.标题 =“",
- "docCategory": "通用生活_其他_其他"
-{},
- "docId": "898E9D6B7EB90FA28C5F077BC2D0B228",
- "title": "三分钟学会易语言",
- "pageNum": 15,
- "size": "40.3KB",
- "hot": "9",
- "fileFormat": "docx",
- "thumbnail": "http://s2.zimgs.cn/ims?kt=MD5&at=document&tv=0_0&sign=yx:-a7gr4xUUL4aSG1EiJjK2rSdGXE=&key=304322F561676F1C18563C0A0C1FA6D9&x.jpg",
- "summary": "三分钟学会编程,易学,易懂,易用,易写,易交流等等,这些都是易语言的特点。可是最近我在网上通过QQ所接触到的一些朋友,却让我感觉到他们学易语言并没有当初我学易语言那么“易”。那下面,我就针对这一部分入门级的朋友讲一下应该怎么来样学习易语言:如果你对编程连一点基础都没有的话,那我们一起来打开易语言(双击e.exe这个程序)在打开后,你会看到,这就是你以后编程中所常见到的程序界面了。如下面图一所示:现",
- "docCategory": "行业资料_行业问答_计算机问答"
-{},
- "docId": "E423D45718A1CB932ECC8FBEDBCAE110",
- "title": "(易语言速成课程)第一章-易语言基础知识",
- "pageNum": 23,
- "size": "1.4M",
- "hot": "7",
- "fileFormat": "doc",
- "thumbnail": "http://s2.zimgs.cn/ims?kt=MD5&at=document&tv=0_0&sign=yx:_sY34jWmr1PQTkbd2Yg-EWDl5Nc=&key=AA122C067CC8D1D6F082F64DBF7D73FE&x.jpg",
- "summary": "第一章 “易语言”基础知识本章主要介绍“易语言”的下载安装,以及运行后的界面。同时介绍一个非常简单的小程序,以帮助用户入门学习。最后介绍编程的输入方法,以及一些初学者会遇到的常见问题。本章学习内容:注意:安装与运行易语言对于电脑的基本要求:“易语言”对硬件要求不高,只要可能运行Win 95以上的机器都可以使用易语言。“易语言”运行的最低计算机配置要求为:1.1 如何下载“易语言” 1.6 如何较好",
- "docCategory": "教育考试_教案_教案"
-{}
- "docId": "E4EB18544CE178271CCC7C5A6340E841",
- "title": "易语言入门教程",
- "pageNum": 5,
- "size": "24.3KB",
- "hot": "8",
- "fileFormat": "docx",
- "thumbnail": "http://s2.zimgs.cn/ims?kt=MD5&at=document&tv=0_0&sign=yx:pNPWPfwBttnzSI2HEyOlLjFjErY=&key=E610F37380F0440EDBD7702B7DE298BB&x.jpg",
- "summary": "如果你是一个刚接触易语言或者是一个连编程都没有接触过的顶级菜鸟、超级新手的话,那么你千万不要错过以下的内容哦!以下内容是“易语言菜鸟之家”结合了众多新手朋友们的困惑和疑问而整理出的经典问题集,如果你刚接触易语言,还不知道自己如何入门,不清楚自己如何去学习这们编程语言,或者你对编程一窍不通的话,看了以下的内容,应该可以让你找到自己的入门路口!1、什么是易语言?它和VB、C语言、C++等有什么区别和相",
- "docCategory": "行业资料_行业问答_计算机问答"
- "tip": "此接口由您要数据独家开发,购买开源接口源码联系WX:gzdswj"
| 错误码 | 类型 | 说明 |
|---|---|---|
| 403 | int | 没有权限 |
| 400 | int | 参数传递不正确 |
| 500 | int | 服务器内部错误 |
<?php
/**
* API请求DEMO
*
* 本demo支持常见的HTTP请求方法(GET/POST/PUT/DELETE等)
*/
//基本配置
$api_key = '你的接口密钥,登录控制台后在密钥管理页面申请';
$secret_key = '';
// API请求示例:
try {
$client = new ApiClient($api_key, $secret_key);
$client->setTimeout(10);
$client->setVerifySSL(false); // 关闭SSL验证
// GET请求示例
echo "=== 开始GET请求 ===\n";
$response = $client->get('https://www.ninyao.cn/api/kkzs/index', [
'key' => $api_key,
'key2' => '其他参数'
]);
print_r($response);
//print_r($client->getLastRequestInfo());
/*
// POST表单示例
echo "\n=== 开始POST请求 ===\n";
$response = $client->post('接口地址', [
'key' => $api_key,
'key2' => '其他参数'
]);
print_r($response);
print_r($client->getLastRequestInfo());
// POST JSON示例
echo "\n=== 开始POST JSON请求 ===\n";
$response = $client->postJson('接口地址', [
'key' => $api_key,
'key2' => '其他参数'
]);
print_r($response);
print_r($client->getLastRequestInfo());
*/
} catch (ApiClientException $e) {
echo "API请求错误: " . $e->getMessage();
if ($e->getCode() > 0) {
echo " (HTTP状态码: " . $e->getCode() . ")";
}
print_r($client->getLastRequestInfo() ?? []);
}
/**
* API客户端类
*
* 提供了一个简单的HTTP API客户端实现,支持常见的HTTP请求方法(GET/POST/PUT/DELETE等)
* 具有以下主要功能:
* - 支持 API 密钥和签名认证
* - 可配置请求超时和SSL验证
* - 支持自定义请求头
* - 支持表单和JSON格式的请求体
* - 自动解析响应结果
* - 提供详细的请求信息记录
*
* 使用示例:
* ```
* $client = new ApiClient('https://api.example.com', 'api_key', 'secret_key');
* $response = $client->get('/users', ['page' => 1]);
* ```
*
* @throws ApiClientException 当API请求失败时抛出异常
*/
class ApiClient
{
private $apiKey;
private $secretKey;
private $timeout = 30;
private $verifySSL = true;
private $lastRequestInfo = [];
private $defaultHeaders = [];
/**
* 构造函数
*
* @param string $apiKey API密钥(可选)
* @param string $secretKey 签名密钥(可选)
*/
public function __construct(string $apiKey = '', string $secretKey = '')
{
$this->apiKey = $apiKey;
$this->secretKey = $secretKey;
}
/**
* 设置请求超时时间(秒)
*/
public function setTimeout(int $seconds): self
{
$this->timeout = $seconds;
return $this;
}
/**
* 设置是否验证SSL证书
*/
public function setVerifySSL(bool $verify): self
{
$this->verifySSL = $verify;
return $this;
}
/**
* 添加默认请求头
*/
public function addDefaultHeader(string $name, string $value): self
{
$this->defaultHeaders[$name] = $value;
return $this;
}
/**
* 发送GET请求
*
* @param string $endpoint 接口端点
* @param array $query 查询参数
* @param array $headers 额外请求头
*/
public function get(string $endpoint, array $query = [], array $headers = []): array
{
return $this->request('GET', $endpoint, [
'query' => $query,
'headers' => $headers
]);
}
/**
* 发送POST请求(表单格式)
*
* @param string $endpoint 接口端点
* @param array $data POST数据
* @param array $headers 额外请求头
*/
public function post(string $endpoint, array $data = [], array $headers = []): array
{
return $this->request('POST', $endpoint, [
'form_data' => $data,
'headers' => $headers
]);
}
/**
* 发送POST请求(JSON格式)
*
* @param string $endpoint 接口端点
* @param array $data POST数据
* @param array $headers 额外请求头
*/
public function postJson(string $endpoint, array $data = [], array $headers = []): array
{
return $this->request('POST', $endpoint, [
'json' => $data,
'headers' => array_merge(['Content-Type' => 'application/json'], $headers)
]);
}
/**
* 发送PUT请求
*/
public function put(string $endpoint, array $data = [], array $headers = []): array
{
return $this->request('PUT', $endpoint, [
'json' => $data,
'headers' => $headers
]);
}
/**
* 发送DELETE请求
*/
public function delete(string $endpoint, array $data = [], array $headers = []): array
{
return $this->request('DELETE', $endpoint, [
'json' => $data,
'headers' => $headers
]);
}
/**
* 获取最后一次请求的详细信息
*/
public function getLastRequestInfo(): array
{
return $this->lastRequestInfo;
}
/**
* 基础请求方法
*/
private function request(string $method, string $endpoint, array $options = []): array
{
// 初始化cURL
$ch = curl_init();
$url = ltrim($endpoint, '/');
// 准备请求头
$headers = $this->prepareHeaders($options['headers'] ?? []);
// 处理查询参数
if (!empty($options['query'])) {
$url .= '?' . http_build_query($options['query']);
}
// 处理请求体
$postData = null;
if (isset($options['form_data'])) {
$postData = http_build_query($options['form_data']);
$headers[] = 'Content-Type: application/x-www-form-urlencoded';
} elseif (isset($options['json'])) {
$postData = json_encode($options['json']);
$headers[] = 'Content-Type: application/json';
}
// 设置cURL选项
curl_setopt_array($ch, [
CURLOPT_URL => $url,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => $method,
CURLOPT_HTTPHEADER => $headers,
CURLOPT_TIMEOUT => $this->timeout,
CURLOPT_SSL_VERIFYPEER => $this->verifySSL,
CURLOPT_SSL_VERIFYHOST => $this->verifySSL,
CURLOPT_HEADER => true,
]);
if ($method !== 'GET' && $postData !== null) {
curl_setopt($ch, CURLOPT_POSTFIELDS, $postData);
}
// 执行请求
$response = curl_exec($ch);
$error = curl_error($ch);
$info = $this->lastRequestInfo = curl_getinfo($ch);
curl_close($ch);
// 处理错误
if ($error) {
throw new ApiClientException("cURL请求失败: " . $error);
}
// 分离响应头和响应体
$headerSize = $info['header_size'];
$responseHeaders = substr($response, 0, $headerSize);
$responseBody = substr($response, $headerSize);
// 解析响应
$result = json_decode($responseBody, true) ?? $responseBody;
// 检查HTTP状态码
if ($info['http_code'] >= 400) {
$errorMsg = is_array($result) ? ($result['message'] ?? $responseBody) : $responseBody;
throw new ApiClientException("API请求失败: " . $errorMsg, $info['http_code']);
}
return [
'status' => $info['http_code'],
'headers' => $this->parseHeaders($responseHeaders),
'data' => $result
];
}
/**
* 准备请求头(自动添加签名)
*/
private function prepareHeaders(array $headers): array
{
// 合并默认头
$headers = array_merge($this->defaultHeaders, $headers);
// 添加签名头
if ($this->apiKey && $this->secretKey) {
$timestamp = time();
$signString = "key={$this->apiKey}×tamp={$timestamp}";
$signature = hash_hmac('sha256', $signString, $this->secretKey);
$headers['X-Api-Key'] = $this->apiKey;
$headers['X-Api-Timestamp'] = $timestamp;
$headers['X-Api-Sign'] = $signature;
}
// 转换为cURL格式
$curlHeaders = [];
foreach ($headers as $name => $value) {
$curlHeaders[] = "$name: $value";
}
return $curlHeaders;
}
/**
* 解析响应头
*/
private function parseHeaders(string $headers): array
{
$parsed = [];
foreach (explode("\r\n", $headers) as $i => $line) {
if ($i === 0) {
$parsed['HTTP_CODE'] = $line;
} else {
$parts = explode(': ', $line, 2);
if (count($parts) === 2) {
$parsed[$parts[0]] = $parts[1];
}
}
}
return $parsed;
}
}
class ApiClientException extends \Exception
{
// 自定义异常类
}
/**
* 原生JS通用API请求函数(支持GET/POST,JSON格式)
* @param {string} url - API接口完整地址
* @param {string} method - 请求方法,仅支持GET/POST
* @param {object} [data={}] - 请求参数(GET拼接到URL,POST作为JSON请求体)
* @returns {Promise} - 返回接口响应的JSON数据
*/
async function requestApi(url, method, data = {}) {
try {
// 处理GET请求:拼接参数到URL
let requestUrl = url;
if (method.toUpperCase() === 'GET' && Object.keys(data).length > 0) {
const params = new URLSearchParams(data).toString();
requestUrl = `${requestUrl}${requestUrl.includes('?') ? '&' : '?'}${params}`;
}
// 配置请求选项
const requestOptions = {
method: method.toUpperCase(),
headers: { 'Content-Type': 'application/json' },
credentials: 'include' // 跨域时携带Cookie,不需要可改为omit
};
// 处理POST请求:设置JSON请求体
if (method.toUpperCase() === 'POST') {
requestOptions.body = JSON.stringify(data);
}
// 发送请求并处理响应
const response = await fetch(requestUrl, requestOptions);
if (!response.ok) throw new Error(`请求失败:${response.status} ${response.statusText}`);
const result = await response.json(); // 自动解析JSON响应
return result;
} catch (error) {
console.error('API请求错误:', error.message);
throw error; // 抛出错误供调用方处理
}
}
// -------------------------- 使用示例 --------------------------
// 1. GET请求示例(查询数据)
async function testGet() {
try {
const data = await requestApi(
'https://api.example.com/user/list', // 替换为实际接口地址
'GET',
{ page: 1, size: 10, keyword: 'test' } // GET请求参数
);
console.log('GET请求成功:', data);
// 业务逻辑处理...
} catch (err) {
alert('GET请求失败:' + err.message);
}
}
// 2. POST请求示例(提交数据)
async function testPost() {
try {
const data = await requestApi(
'https://api.example.com/user/login', // 替换为实际接口地址
'POST',
{ username: 'admin', password: '123456' } // POST请求体数据
);
console.log('POST请求成功:', data);
// 业务逻辑处理...
} catch (err) {
alert('POST请求失败:' + err.message);
}
}
// 执行请求(按需调用)
// testGet();
// testPost();
import okhttp3.*;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;
/**
* Java 单文件实现GET/POST(JSON) API请求
* 基于OkHttp和Jackson,复制后直接使用(需添加Maven/Gradle依赖)
*/
public class ApiRequest {
// 全局OkHttpClient实例(复用连接池)
private static final OkHttpClient OK_HTTP_CLIENT = new OkHttpClient.Builder()
.connectTimeout(10, TimeUnit.SECONDS)
.readTimeout(10, TimeUnit.SECONDS)
.writeTimeout(10, TimeUnit.SECONDS)
.build();
// Jackson JSON解析工具
private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();
/**
* GET请求方法
* @param url 接口地址
* @param params URL参数键值对
* @return 接口响应字符串
* @throws IOException 网络异常
*/
public static String doGet(String url, Map params) throws IOException {
HttpUrl.Builder urlBuilder = HttpUrl.parse(url).newBuilder();
if (params != null && !params.isEmpty()) {
for (Map.Entry entry : params.entrySet()) {
urlBuilder.addQueryParameter(entry.getKey(), entry.getValue());
}
}
Request request = new Request.Builder().url(urlBuilder.build()).get().build();
try (Response response = OK_HTTP_CLIENT.newCall(request).execute()) {
if (!response.isSuccessful()) {
throw new IOException("GET请求失败:" + response.code() + " " + response.message());
}
return response.body() != null ? response.body().string() : "";
}
}
/**
* POST(JSON)请求方法
* @param url 接口地址
* @param jsonStr JSON请求体字符串
* @return 接口响应字符串
* @throws IOException 网络异常
*/
public static String doPostJson(String url, String jsonStr) throws IOException {
MediaType mediaType = MediaType.parse("application/json; charset=utf-8");
RequestBody requestBody = RequestBody.create(mediaType, jsonStr);
Request request = new Request.Builder().url(url).post(requestBody).build();
try (Response response = OK_HTTP_CLIENT.newCall(request).execute()) {
if (!response.isSuccessful()) {
throw new IOException("POST请求失败:" + response.code() + " " + response.message());
}
return response.body() != null ? response.body().string() : "";
}
}
/**
* 格式化JSON字符串(便于阅读)
* @param jsonStr 原始JSON字符串
* @return 格式化后的JSON
* @throws IOException 解析异常
*/
public static String formatJson(String jsonStr) throws IOException {
if (jsonStr == null || jsonStr.isEmpty()) {
return "";
}
Object jsonObj = OBJECT_MAPPER.readValue(jsonStr, Object.class);
return OBJECT_MAPPER.writerWithDefaultPrettyPrinter().writeValueAsString(jsonObj);
}
// 主方法:测试GET/POST请求
public static void main(String[] args) {
try {
// ------------------- 测试GET请求 -------------------
String getUrl = "https://api.example.com/user/list"; // 替换为实际接口地址
Map getParams = new HashMap<>();
getParams.put("page", "1");
getParams.put("size", "10");
getParams.put("keyword", "test");
String getResponse = doGet(getUrl, getParams);
System.out.println("=== GET请求响应结果 ===");
System.out.println(formatJson(getResponse));
System.out.println("------------------------");
// ------------------- 测试POST请求 -------------------
String postUrl = "https://api.example.com/user/login"; // 替换为实际接口地址
Map postData = new HashMap<>();
postData.put("username", "admin");
postData.put("password", "123456");
String jsonStr = OBJECT_MAPPER.writeValueAsString(postData);
String postResponse = doPostJson(postUrl, jsonStr);
System.out.println("=== POST请求响应结果 ===");
System.out.println(formatJson(postResponse));
} catch (IOException e) {
e.printStackTrace();
}
}
}
package main
import (
"bytes"
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
"net/url"
"time"
)
// 全局HTTP客户端,设置超时时间
var httpClient = &http.Client{
Timeout: 10 * time.Second, // 请求超时时间10秒
}
// DoGet 发送GET请求,自动拼接URL参数
// urlStr: 接口地址
// params: URL查询参数(键值对)
// 返回:响应体字符串、错误信息
func DoGet(urlStr string, params map[string]string) (string, error) {
// 解析基础URL
parsedUrl, err := url.Parse(urlStr)
if err != nil {
return "", fmt.Errorf("URL解析失败: %v", err)
}
// 拼接查询参数
query := parsedUrl.Query()
for key, value := range params {
query.Add(key, value)
}
parsedUrl.RawQuery = query.Encode()
// 发送GET请求
resp, err := httpClient.Get(parsedUrl.String())
if err != nil {
return "", fmt.Errorf("GET请求失败: %v", err)
}
defer resp.Body.Close() // 确保响应体关闭
// 检查响应状态码
if resp.StatusCode < 200 || resp.StatusCode >= 300 {
return "", fmt.Errorf("请求返回异常状态码: %d", resp.StatusCode)
}
// 读取响应体
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
return "", fmt.Errorf("读取响应体失败: %v", err)
}
return string(body), nil
}
// DoPostJson 发送POST请求,JSON格式请求体
// urlStr: 接口地址
// data: 请求体数据(任意可序列化为JSON的结构体/Map)
// 返回:响应体字符串、错误信息
func DoPostJson(urlStr string, data interface{}) (string, error) {
// 将数据序列化为JSON字节流
jsonData, err := json.Marshal(data)
if err != nil {
return "", fmt.Errorf("JSON序列化失败: %v", err)
}
// 发送POST请求
resp, err := httpClient.Post(urlStr, "application/json", bytes.NewBuffer(jsonData))
if err != nil {
return "", fmt.Errorf("POST请求失败: %v", err)
}
defer resp.Body.Close()
// 检查响应状态码
if resp.StatusCode < 200 || resp.StatusCode >= 300 {
return "", fmt.Errorf("请求返回异常状态码: %d", resp.StatusCode)
}
// 读取响应体
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
return "", fmt.Errorf("读取响应体失败: %v", err)
}
return string(body), nil
}
// FormatJson 格式化JSON字符串(便于控制台阅读)
func FormatJson(jsonStr string) string {
var prettyJson bytes.Buffer
err := json.Indent(&prettyJson, []byte(jsonStr), "", " ")
if err != nil {
return jsonStr // 格式化失败则返回原字符串
}
return prettyJson.String()
}
func main() {
// ------------------- 测试GET请求 -------------------
fmt.Println("=== 开始测试GET请求 ===")
getUrl := "https://api.example.com/user/list" // 替换为实际接口地址
getParams := map[string]string{
"page": "1",
"size": "10",
"keyword": "test",
}
getResp, err := DoGet(getUrl, getParams)
if err != nil {
fmt.Printf("GET请求出错: %v\n", err)
} else {
fmt.Println("GET请求响应结果:\n", FormatJson(getResp))
}
fmt.Println("------------------------")
// ------------------- 测试POST请求 -------------------
fmt.Println("=== 开始测试POST请求 ===")
postUrl := "https://api.example.com/user/login" // 替换为实际接口地址
// 定义POST请求体(可替换为自定义结构体)
postData := map[string]string{
"username": "admin",
"password": "123456",
}
postResp, err := DoPostJson(postUrl, postData)
if err != nil {
fmt.Printf("POST请求出错: %v\n", err)
} else {
fmt.Println("POST请求响应结果:\n", FormatJson(postResp))
}
}
import requests
import json
# 配置全局请求超时时间(单位:秒)
TIMEOUT = 10
def do_get(url: str, params: dict = None) -> str:
"""
发送GET请求
:param url: 接口地址
:param params: URL查询参数(字典)
:return: 响应体字符串(格式化后的JSON)
:raises Exception: 请求失败时抛出异常
"""
try:
# 发送GET请求
response = requests.get(url, params=params, timeout=TIMEOUT)
# 检查响应状态码
response.raise_for_status()
# 返回格式化后的JSON字符串
return json.dumps(response.json(), indent=2, ensure_ascii=False)
except requests.exceptions.RequestException as e:
raise Exception(f"GET请求失败: {str(e)}")
def do_post_json(url: str, data: dict = None) -> str:
"""
发送POST请求(JSON格式请求体)
:param url: 接口地址
:param data: JSON请求体(字典)
:return: 响应体字符串(格式化后的JSON)
:raises Exception: 请求失败时抛出异常
"""
try:
# 发送POST请求,自动设置Content-Type为application/json
response = requests.post(url, json=data, timeout=TIMEOUT)
# 检查响应状态码
response.raise_for_status()
# 返回格式化后的JSON字符串
return json.dumps(response.json(), indent=2, ensure_ascii=False)
except requests.exceptions.RequestException as e:
raise Exception(f"POST请求失败: {str(e)}")
if __name__ == "__main__":
# ------------------- 测试GET请求 -------------------
print("=== 开始测试GET请求 ===")
get_url = "https://api.example.com/user/list" # 替换为实际接口地址
get_params = {
"page": 1,
"size": 10,
"keyword": "test"
}
try:
get_resp = do_get(get_url, get_params)
print("GET请求响应结果:\n", get_resp)
except Exception as e:
print(e)
print("-" * 40)
# ------------------- 测试POST请求 -------------------
print("=== 开始测试POST请求 ===")
post_url = "https://api.example.com/user/login" # 替换为实际接口地址
post_data = {
"username": "admin",
"password": "123456"
}
try:
post_resp = do_post_json(post_url, post_data)
print("POST请求响应结果:\n", post_resp)
except Exception as e:
print(e)
const http = require('http');
const https = require('https');
const querystring = require('querystring');
/**
* 通用请求函数(支持GET/POST,JSON格式)
* @param {string} url - 接口完整地址
* @param {string} method - GET/POST
* @param {object} [data={}] - 请求参数(GET拼URL,POST为JSON体)
* @returns {Promise} - 响应JSON数据
*/
function requestApi(url, method, data = {}) {
return new Promise((resolve, reject) => {
// 解析URL
const urlObj = new URL(url);
const isHttps = urlObj.protocol === 'https:';
const client = isHttps ? https : http;
// 处理GET参数
let path = urlObj.pathname;
if (method.toUpperCase() === 'GET' && Object.keys(data).length > 0) {
const params = querystring.stringify(data);
path += (urlObj.search ? '&' : '?') + params;
}
// 处理POST请求体
let postData = '';
if (method.toUpperCase() === 'POST') {
postData = JSON.stringify(data);
}
// 配置请求选项
const options = {
hostname: urlObj.hostname,
port: urlObj.port || (isHttps ? 443 : 80),
path: path + urlObj.search,
method: method.toUpperCase(),
headers: {
'Content-Type': 'application/json; charset=utf-8',
'Content-Length': Buffer.byteLength(postData)
}
};
// 发送请求
const req = client.request(options, (res) => {
let rawData = '';
res.on('data', (chunk) => { rawData += chunk; });
res.on('end', () => {
try {
// 解析JSON响应
const result = JSON.parse(rawData);
resolve(result);
} catch (err) {
reject(new Error(`响应解析失败: ${err.message}`));
}
});
});
// 错误处理
req.on('error', (err) => {
reject(new Error(`请求失败: ${err.message}`));
});
// 写入POST请求体
if (method.toUpperCase() === 'POST') {
req.write(postData);
}
req.end();
});
}
// 测试主函数
async function main() {
try {
// ------------------- 测试GET请求 -------------------
console.log('=== 开始测试GET请求 ===');
const getUrl = 'https://api.example.com/user/list'; // 替换为实际接口
const getParams = { page: 1, size: 10, keyword: 'test' };
const getResult = await requestApi(getUrl, 'GET', getParams);
console.log('GET请求响应:', JSON.stringify(getResult, null, 2));
console.log('------------------------');
// ------------------- 测试POST请求 -------------------
console.log('=== 开始测试POST请求 ===');
const postUrl = 'https://api.example.com/user/login'; // 替换为实际接口
const postData = { username: 'admin', password: '123456' };
const postResult = await requestApi(postUrl, 'POST', postData);
console.log('POST请求响应:', JSON.stringify(postResult, null, 2));
} catch (err) {
console.error('请求出错:', err.message);
}
}
// 执行测试
main();
#include
#include
#include
#include
// 定义缓冲区结构体,用于存储响应数据
typedef struct {
char* data;
size_t size;
} ResponseBuffer;
// libcurl的写回调函数,将响应数据写入缓冲区
static size_t write_callback(void* contents, size_t size, size_t nmemb, void* userp) {
size_t realsize = size * nmemb;
ResponseBuffer* buffer = (ResponseBuffer*)userp;
// 重新分配内存存储响应数据
char* temp = realloc(buffer->data, buffer->size + realsize + 1);
if (temp == NULL) {
fprintf(stderr, "内存分配失败!\n");
return 0;
}
buffer->data = temp;
memcpy(&(buffer->data[buffer->size]), contents, realsize);
buffer->size += realsize;
buffer->data[buffer->size] = '\0'; // 字符串结束符
return realsize;
}
// 初始化响应缓冲区
void init_buffer(ResponseBuffer* buffer) {
buffer->data = malloc(1);
buffer->size = 0;
}
// 释放响应缓冲区内存
void free_buffer(ResponseBuffer* buffer) {
free(buffer->data);
buffer->data = NULL;
buffer->size = 0;
}
/**
* 发送GET请求
* @param url 接口地址
* @param params URL参数(格式:"key1=value1&key2=value2",传NULL则无参数)
* @return 响应字符串(需手动free释放),失败返回NULL
*/
char* http_get(const char* url, const char* params) {
CURL* curl = curl_easy_init();
if (!curl) {
fprintf(stderr, "CURL初始化失败!\n");
return NULL;
}
ResponseBuffer buffer;
init_buffer(&buffer);
// 拼接GET请求的URL和参数
char* full_url = NULL;
if (params && strlen(params) > 0) {
full_url = (char*)malloc(strlen(url) + strlen(params) + 2);
sprintf(full_url, "%s?%s", url, params);
} else {
full_url = (char*)malloc(strlen(url) + 1);
strcpy(full_url, url);
}
// 设置CURL选项
curl_easy_setopt(curl, CURLOPT_URL, full_url);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_callback);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &buffer);
curl_easy_setopt(curl, CURLOPT_TIMEOUT, 10L); // 超时时间10秒
curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L); // 跟随重定向
// 执行GET请求
CURLcode res = curl_easy_perform(curl);
if (res != CURLE_OK) {
fprintf(stderr, "GET请求失败: %s\n", curl_easy_strerror(res));
free_buffer(&buffer);
free(full_url);
curl_easy_cleanup(curl);
return NULL;
}
// 检查响应状态码
long response_code;
curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &response_code);
if (response_code < 200 || response_code >= 300) {
fprintf(stderr, "GET请求返回异常状态码: %ld\n", response_code);
free_buffer(&buffer);
free(full_url);
curl_easy_cleanup(curl);
return NULL;
}
// 释放资源
free(full_url);
curl_easy_cleanup(curl);
// 返回响应数据(需调用者手动free)
return buffer.data;
}
/**
* 发送POST请求(JSON格式请求体)
* @param url 接口地址
* @param json_data JSON请求体字符串
* @return 响应字符串(需手动free释放),失败返回NULL
*/
char* http_post_json(const char* url, const char* json_data) {
CURL* curl = curl_easy_init();
if (!curl) {
fprintf(stderr, "CURL初始化失败!\n");
return NULL;
}
ResponseBuffer buffer;
init_buffer(&buffer);
// 设置CURL选项
curl_easy_setopt(curl, CURLOPT_URL, url);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_callback);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &buffer);
curl_easy_setopt(curl, CURLOPT_TIMEOUT, 10L); // 超时时间10秒
curl_easy_setopt(curl, CURLOPT_POST, 1L); // 启用POST请求
// 设置JSON请求体和请求头
struct curl_slist* headers = NULL;
headers = curl_slist_append(headers, "Content-Type: application/json; charset=utf-8");
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, json_data);
curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, strlen(json_data));
// 执行POST请求
CURLcode res = curl_easy_perform(curl);
if (res != CURLE_OK) {
fprintf(stderr, "POST请求失败: %s\n", curl_easy_strerror(res));
free_buffer(&buffer);
curl_slist_free_all(headers);
curl_easy_cleanup(curl);
return NULL;
}
// 检查响应状态码
long response_code;
curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &response_code);
if (response_code < 200 || response_code >= 300) {
fprintf(stderr, "POST请求返回异常状态码: %ld\n", response_code);
free_buffer(&buffer);
curl_slist_free_all(headers);
curl_easy_cleanup(curl);
return NULL;
}
// 释放资源
curl_slist_free_all(headers);
curl_easy_cleanup(curl);
// 返回响应数据(需调用者手动free)
return buffer.data;
}
int main(void) {
// 初始化libcurl
curl_global_init(CURL_GLOBAL_ALL);
// ------------------- 测试GET请求 -------------------
printf("=== 开始测试GET请求 ===\n");
const char* get_url = "https://api.example.com/user/list"; // 替换为实际接口
const char* get_params = "page=1&size=10&keyword=test"; // GET参数
char* get_resp = http_get(get_url, get_params);
if (get_resp) {
printf("GET请求响应结果:\n%s\n", get_resp);
free(get_resp); // 释放响应内存
}
printf("------------------------\n");
// ------------------- 测试POST请求 -------------------
printf("=== 开始测试POST请求 ===\n");
const char* post_url = "https://api.example.com/user/login"; // 替换为实际接口
const char* post_json = "{\"username\":\"admin\",\"password\":\"123456\"}"; // JSON请求体
char* post_resp = http_post_json(post_url, post_json);
if (post_resp) {
printf("POST请求响应结果:\n%s\n", post_resp);
free(post_resp); // 释放响应内存
}
// 清理libcurl全局资源
curl_global_cleanup();
return 0;
}
#include
#include
#include
#include
// 响应数据缓冲区类,封装内存管理
class ResponseBuffer {
public:
std::string data; // 存储响应数据的字符串,自动管理内存
// libcurl写回调函数,将响应数据写入缓冲区
static size_t WriteCallback(void* contents, size_t size, size_t nmemb, void* userp) {
size_t realSize = size * nmemb;
ResponseBuffer* buffer = static_cast(userp);
buffer->data.append(static_cast(contents), realSize);
return realSize;
}
};
// HTTP请求工具类,封装GET/POST(JSON)方法
class HttpRequester {
private:
CURL* curl; // CURL句柄
long timeout; // 请求超时时间(秒)
public:
// 构造函数:初始化CURL
HttpRequester(long timeout = 10) : timeout(timeout) {
curl_global_init(CURL_GLOBAL_ALL);
curl = curl_easy_init();
if (!curl) {
throw std::runtime_error("CURL初始化失败!");
}
// 设置全局超时
curl_easy_setopt(curl, CURLOPT_TIMEOUT, timeout);
// 跟随HTTP重定向
curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
}
// 析构函数:释放CURL资源
~HttpRequester() {
if (curl) {
curl_easy_cleanup(curl);
}
curl_global_cleanup();
}
// 禁用拷贝构造和赋值,避免资源重复释放
HttpRequester(const HttpRequester&) = delete;
HttpRequester& operator=(const HttpRequester&) = delete;
/**
* 发送GET请求
* @param url 接口地址
* @param params URL参数(格式:"key1=value1&key2=value2")
* @return 响应字符串
* @throws std::runtime_error 请求失败时抛出异常
*/
std::string Get(const std::string& url, const std::string& params = "") {
if (!curl) {
throw std::runtime_error("CURL句柄未初始化");
}
// 拼接完整URL(带参数)
std::string fullUrl = url;
if (!params.empty()) {
fullUrl += "?" + params;
}
ResponseBuffer buffer;
// 设置CURL选项
curl_easy_setopt(curl, CURLOPT_URL, fullUrl.c_str());
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, ResponseBuffer::WriteCallback);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &buffer);
// 执行GET请求
CURLcode res = curl_easy_perform(curl);
if (res != CURLE_OK) {
throw std::runtime_error("GET请求失败: " + std::string(curl_easy_strerror(res)));
}
// 检查响应状态码
long responseCode;
curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &responseCode);
if (responseCode < 200 || responseCode >= 300) {
throw std::runtime_error("GET请求返回异常状态码: " + std::to_string(responseCode));
}
return buffer.data;
}
/**
* 发送POST请求(JSON格式请求体)
* @param url 接口地址
* @param jsonData JSON请求体字符串
* @return 响应字符串
* @throws std::runtime_error 请求失败时抛出异常
*/
std::string PostJson(const std::string& url, const std::string& jsonData) {
if (!curl) {
throw std::runtime_error("CURL句柄未初始化");
}
ResponseBuffer buffer;
// 设置POST请求基础选项
curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
curl_easy_setopt(curl, CURLOPT_POST, 1L); // 启用POST方法
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, jsonData.c_str()); // 设置请求体
curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, jsonData.length()); // 设置请求体长度
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, ResponseBuffer::WriteCallback);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &buffer);
// 设置JSON请求头
struct curl_slist* headers = nullptr;
headers = curl_slist_append(headers, "Content-Type: application/json; charset=utf-8");
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
// 执行POST请求
CURLcode res = curl_easy_perform(curl);
// 释放请求头链表(无论请求成功与否都要释放)
curl_slist_free_all(headers);
if (res != CURLE_OK) {
throw std::runtime_error("POST请求失败: " + std::string(curl_easy_strerror(res)));
}
// 检查响应状态码
long responseCode;
curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &responseCode);
if (responseCode < 200 || responseCode >= 300) {
throw std::runtime_error("POST请求返回异常状态码: " + std::to_string(responseCode));
}
return buffer.data;
}
};
// 主函数:测试GET/POST请求
int main() {
try {
// 创建HTTP请求器实例
HttpRequester requester;
// ------------------- 测试GET请求 -------------------
std::cout << "=== 开始测试GET请求 ===" << std::endl;
std::string getUrl = "https://api.example.com/user/list"; // 替换为实际接口
std::string getParams = "page=1&size=10&keyword=test"; // GET参数
std::string getResp = requester.Get(getUrl, getParams);
std::cout << "GET请求响应结果:\n" << getResp << std::endl;
std::cout << "------------------------" << std::endl;
// ------------------- 测试POST请求 -------------------
std::cout << "=== 开始测试POST请求 ===" << std::endl;
std::string postUrl = "https://api.example.com/user/login"; // 替换为实际接口
std::string postJson = R"({"username":"admin","password":"123456"})"; // JSON请求体(原生字符串避免转义)
std::string postResp = requester.PostJson(postUrl, postJson);
std::cout << "POST请求响应结果:\n" << postResp << std::endl;
} catch (const std::exception& e) {
// 捕获所有异常并打印
std::cerr << "请求出错: " << e.what() << std::endl;
return 1;
}
return 0;
}
using System;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
using System.Text.Json;
///
/// HTTP请求工具类,封装GET/POST(JSON)请求
///
public class HttpRequester
{
// 静态HttpClient实例(推荐单例使用,避免频繁创建释放连接)
private static readonly HttpClient _httpClient = new HttpClient
{
Timeout = TimeSpan.FromSeconds(10) // 设置10秒超时
};
///
/// 发送GET请求
///
/// 接口完整地址
/// URL查询参数(键值对)
/// 格式化后的JSON响应字符串
/// 请求失败时抛出异常
public static async Task GetAsync(string url, System.Collections.Generic.Dictionary paramsDict = null)
{
// 拼接查询参数
if (paramsDict != null && paramsDict.Count > 0)
{
var queryBuilder = new System.Text.StringBuilder();
foreach (var pair in paramsDict)
{
queryBuilder.Append($"{Uri.EscapeDataString(pair.Key)}={Uri.EscapeDataString(pair.Value)}&");
}
string query = queryBuilder.ToString().TrimEnd('&');
url += $"{(url.Contains("?") ? "&" : "?")}{query}";
}
// 发送GET请求
using var response = await _httpClient.GetAsync(url);
// 检查响应状态码,非2xx则抛出异常
response.EnsureSuccessStatusCode();
// 读取响应并格式化JSON
string jsonResponse = await response.Content.ReadAsStringAsync();
return FormatJson(jsonResponse);
}
///
/// 发送POST请求(JSON格式请求体)
///
/// 接口完整地址
/// 请求体数据(任意可序列化的对象)
/// 格式化后的JSON响应字符串
/// 请求失败时抛出异常
public static async Task PostJsonAsync(string url, T data)
{
// 将对象序列化为JSON字符串
string jsonData = JsonSerializer.Serialize(data, new JsonSerializerOptions { WriteIndented = false });
// 构造JSON请求体
using var content = new StringContent(jsonData, Encoding.UTF8, "application/json");
// 发送POST请求
using var response = await _httpClient.PostAsync(url, content);
// 检查响应状态码
response.EnsureSuccessStatusCode();
// 读取响应并格式化JSON
string jsonResponse = await response.Content.ReadAsStringAsync();
return FormatJson(jsonResponse);
}
///
/// 格式化JSON字符串(便于阅读)
///
private static string FormatJson(string json)
{
if (string.IsNullOrEmpty(json)) return json;
var jsonDoc = JsonDocument.Parse(json);
return JsonSerializer.Serialize(jsonDoc, new JsonSerializerOptions { WriteIndented = true });
}
}
///
/// 测试类,包含主函数
///
class Program
{
// C# 7.1+支持Main方法为async
static async Task Main(string[] args)
{
try
{
// ------------------- 测试GET请求 -------------------
Console.WriteLine("=== 开始测试GET请求 ===");
string getUrl = "https://api.example.com/user/list"; // 替换为实际接口
var getParams = new System.Collections.Generic.Dictionary
{
{ "page", "1" },
{ "size", "10" },
{ "keyword", "test" }
};
string getResponse = await HttpRequester.GetAsync(getUrl, getParams);
Console.WriteLine("GET请求响应结果:\n" + getResponse);
Console.WriteLine("------------------------");
// ------------------- 测试POST请求 -------------------
Console.WriteLine("=== 开始测试POST请求 ===");
string postUrl = "https://api.example.com/user/login"; // 替换为实际接口
// 定义请求体对象(可替换为自定义类)
var postData = new
{
username = "admin",
password = "123456"
};
string postResponse = await HttpRequester.PostJsonAsync(postUrl, postData);
Console.WriteLine("POST请求响应结果:\n" + postResponse);
}
catch (HttpRequestException ex)
{
Console.WriteLine($"请求失败: {ex.Message}");
if (ex.InnerException != null)
{
Console.WriteLine($"内部异常: {ex.InnerException.Message}");
}
}
catch (Exception ex)
{
Console.WriteLine($"程序异常: {ex.Message}");
}
// 防止控制台立即关闭
Console.WriteLine("\n按任意键退出...");
Console.ReadKey();
}
}
' 引入必要的命名空间
Imports System
Imports System.Net.Http
Imports System.Text
Imports System.Threading.Tasks
Imports System.Collections.Generic
Imports System.Text.Json
Imports System.Net.Http.Headers
'''
''' HTTP请求工具类,封装GET/POST(JSON)核心逻辑
''' 基于.NET内置HttpClient,支持异步请求、JSON序列化/反序列化
'''
Public Class HttpHelper
' 静态HttpClient单例(推荐单例使用,避免端口耗尽)
Private Shared ReadOnly _httpClient As New HttpClient With {
.Timeout = TimeSpan.FromSeconds(10) ' 设置10秒请求超时
}
'''
''' 发送GET请求,自动拼接URL参数
'''
''' 接口基础地址
''' URL查询参数(键值对)
''' 格式化后的JSON响应字符串
Public Shared Async Function SendGetRequestAsync(baseUrl As String, Optional parameters As Dictionary(Of String, String) = Nothing) As Task(Of String)
Try
' 拼接查询参数
Dim requestUrl As String = baseUrl
If parameters IsNot Nothing AndAlso parameters.Count > 0 Then
Dim queryBuilder As New StringBuilder()
For Each pair In parameters
queryBuilder.Append($"{Uri.EscapeDataString(pair.Key)}={Uri.EscapeDataString(pair.Value)}&")
Next
Dim query As String = queryBuilder.ToString().TrimEnd("&"c)
requestUrl &= If(requestUrl.Contains("?"), "&", "?") & query
End If
' 发送GET请求并验证状态码
Dim response As HttpResponseMessage = Await _httpClient.GetAsync(requestUrl)
response.EnsureSuccessStatusCode()
' 读取响应并格式化JSON
Dim responseJson As String = Await response.Content.ReadAsStringAsync()
Return FormatJsonString(responseJson)
Catch ex As HttpRequestException
Throw New Exception($"GET请求失败:{ex.Message}", ex)
End Try
End Function
'''
''' 发送POST请求(JSON格式请求体)
'''
''' 请求体数据类型
''' 接口完整地址
''' 请求体数据(任意可序列化对象)
''' 格式化后的JSON响应字符串
Public Shared Async Function SendPostJsonRequestAsync(Of T)(apiUrl As String, requestData As T) As Task(Of String)
Try
' 将对象序列化为JSON字符串
Dim jsonBody As String = JsonSerializer.Serialize(requestData, New JsonSerializerOptions With {.WriteIndented = False})
' 构造JSON请求体
Dim content As New StringContent(jsonBody, Encoding.UTF8, "application/json")
' 发送POST请求并验证状态码
Dim response As HttpResponseMessage = Await _httpClient.PostAsync(apiUrl, content)
response.EnsureSuccessStatusCode()
' 读取响应并格式化JSON
Dim responseJson As String = Await response.Content.ReadAsStringAsync()
Return FormatJsonString(responseJson)
Catch ex As HttpRequestException
Throw New Exception($"POST请求失败:{ex.Message}", ex)
End Try
End Function
'''
''' 添加全局请求头(如Token、API Key)
'''
''' 请求头名称
''' 请求头值
Public Shared Sub AddGlobalHeader(headerName As String, headerValue As String)
If Not _httpClient.DefaultRequestHeaders.Contains(headerName) Then
_httpClient.DefaultRequestHeaders.Add(headerName, headerValue)
End If
End Sub
'''
''' 格式化JSON字符串,提升可读性
'''
''' 原始JSON字符串
''' 格式化后的JSON
Private Shared Function FormatJsonString(rawJson As String) As String
If String.IsNullOrEmpty(rawJson) Then Return rawJson
Dim jsonDoc As JsonDocument = JsonDocument.Parse(rawJson)
Return JsonSerializer.Serialize(jsonDoc, New JsonSerializerOptions With {.WriteIndented = True})
End Function
End Class
'''
''' 测试程序入口,演示GET/POST请求的使用
'''
Module Program
' VB.NET主函数,异步执行测试逻辑
Sub Main()
' 同步等待异步方法执行(控制台程序专用)
TestApiRequestsAsync().GetAwaiter().GetResult()
' 防止控制台立即关闭
Console.WriteLine(vbCrLf & "按任意键退出程序...")
Console.ReadKey()
End Sub
'''
''' 测试GET和POST API请求
'''
Private Async Function TestApiRequestsAsync() As Task
Try
' 可选:添加全局请求头(如Token认证)
' HttpHelper.AddGlobalHeader("Authorization", "Bearer your_token_here")
' HttpHelper.AddGlobalHeader("X-API-Key", "your_api_key_here")
' ------------------- 测试GET请求 -------------------
Console.WriteLine("=== 开始执行GET请求 ===")
Dim getUrl As String = "https://api.example.com/user/list" ' 替换为实际接口地址
Dim getParams As New Dictionary(Of String, String) From {
{"page", "1"},
{"size", "10"},
{"keyword", "vb.net_test"}
}
Dim getResponse As String = Await HttpHelper.SendGetRequestAsync(getUrl, getParams)
Console.WriteLine("GET请求响应结果:" & vbCrLf & getResponse)
Console.WriteLine("------------------------")
' ------------------- 测试POST请求 -------------------
Console.WriteLine("=== 开始执行POST请求 ===")
Dim postUrl As String = "https://api.example.com/user/login" ' 替换为实际接口地址
' 匿名类型请求体(也可替换为自定义实体类)
Dim postData = New With {
.username = "vbnet_admin",
.password = "123456_test",
.rememberMe = True
}
Dim postResponse As String = Await HttpHelper.SendPostJsonRequestAsync(postUrl, postData)
Console.WriteLine("POST请求响应结果:" & vbCrLf & postResponse)
Catch ex As Exception
Console.WriteLine($"请求异常:{ex.Message}")
If ex.InnerException IsNot Nothing Then
Console.WriteLine($"内部异常详情:{ex.InnerException.Message}")
End If
End Try
End Function
End Module