postman变量和脚本功能介绍
1、基本概念——global、collection、environment
在postman中,为了更好的管理各类变量、测试环境以及脚本等,创建了一些概念,包括:globals、collection、environment。其实在postman中,最上层还有一个Workspaces的概念,不过大多数情况我们都使用一个workspace,这里就不多介绍了。
1.1)请求组(collection):
可以将多个请求保存到一个请求组(Collections)中, 好处是: 增加额外Collection变量作用域, 增加公共的PreRequest和Test脚本, 批量执行Collection下的请求, 定义Collection内请求的顺序。
上图中可以看到,左上角“+”可以创建新的collection;点击collection的右侧“。。。”可以Edit现有collection,以及Run、Add folder等功能。
说明:Collection下还可以建文件夹,对请求进一步划分,比如:用户模块、订单模块。
1.2)环境(environment):
通常一个系统具备多个环境,比如:测试、线上。
如上图,点击左上角“+”可以新建一个environment;鼠标指向现有environment,点击右侧“。。。”可以进行编辑。值得提醒的是,当运行时,需要在右上角选中我们想要的环境。
变量有两个value(不光是环境变量,其他变量也是一样的),二者的区别:
- INITAL_VALUE:初始值是在定义变量的元素(集合、环境或全局变量)中设置的值。此值将同步到 Postman 的服务器,并在您共享该元素时与您的团队共享
- CURRENT_VALUE:这些是本地值,不会同步到 Postman 的服务器。如果您更改当前值,它将不会保留在原始共享集合、环境或全局变量中。
1.3)golbal:
细心的朋友已经发现,在environment中,左上角出现了Golbals:
2、变量
变量,在postman中最常见的一个功能,包括设置、读取、作用域等。
2.1)变量作用域:
postman中变量有多个作用域, 越往内的作用域优先级越高(global < collection < environment < …), 举例来说, 如果global作用域和Environment作用域里都有一个变量叫username, 那么最终使用的是Environment作用域里的变量值。
不同作用域变量设置方法:
2.2)定义、使用变量
从上面图可以看到,在UI界面上可以管理globals变量,后面也会降到使用API方式设置、读取globes变量(会同步出现在UI界面上);同样的,对于environment变量也是一样的。(如上面1.2和1.3)
1)通过界面定义变量:
选中某个值,然后点击弹出的菜单点击"Set as new variable":
然后这只变量名、和作用域:
2)管理Collections变量:
选择某个Collection后,点击右侧的“。。。”,然后选择Edit,在右侧界面上会显示Variables。
3)使用变量:
在不同作用域定义好变量后, 然后在某个请求中引用该变量, 从而做到变量复用和统一管理。
使用"{{变量名}}"来引用变量。
2.3)在脚本中操作变量
// 不同作用域设置变量
pm.globals.set("username", "golbals_name");
pm.globals.set("username1", "golbals_name1");
pm.collectionVariables.set("username", "collection_name");
pm.environment.set("username", "environment_name");
pm.variables.set("username", "variable_username"); //临时覆盖, 优先级最高, 请求结束后失效// 获取变量值
console.log(pm.globals.get("username")); //从globals作用域中查询变量
console.log(pm.collectionVariables.get("username"));
console.log(pm.environment.get("username"));
var k = pm.variables.get("username1"); //依次从各个作用域查找
console.log("username:" + k);// 判断
pm.variables.has("username");
pm.environment.has("username");
pm.globals.has("username");// 清理
pm.environment.unset("username");
2.4)data作用域的变量
在UI界面上,选择Collection的Run,在界面中可以选择一个文件
然后准备一个文件,内容如下:(必须是json或者csv格式)
[{"path": "post","value": "1"
}, {"path": "post","value": "2"
}, {"path": "post","value": "3"
}, {"path": "post","value": "4"
}]
另外,在脚本里访问data文件可以使用如下AIP:
pm.iterationData.get("value");
3、脚本
postman API文档:Home - Postman Documentation
3.1)脚本相关概念:
1)脚本执行顺序:
执行每个请求时会依次执行如下脚本:
- Collection级别的pre-request脚本
- Folder级别的pre-request脚本
- Request级别的pre-prequest脚本
- Request级别的test脚本
- Folder级别的test脚本
- Collection级别的test脚本
2)在界面上输入脚本信息:
最常见的就是request级别的脚本,可以在Scripts页签下输入,如下:
可以看到,脚本分两个:pre-request和post-reponse,分别对应请求前处理和请求后处理。
在Collection级别上也可以创建脚本,如下:
同样,如果在Collection下有folder,那么folder上也可以创建scripts。
3.2)常用脚本代码
1)操作变量:
// 设置全局变量
pm.globals.set('variable_key', 'variable_value');
var variable_key = pm.globals.get('variable_key');// 获取全局变量
pm.globals.unset('variable_key');// unset 全局变量// 设置环境变量
pm.environment.set('variable_key', 'variable_value');
var variable_key = pm.environment.get('variable_key');// 获取环境变量
pm.environment.unset('variable_key');// unset 环境变量// 设置临时变量
pm.variables.set('variable_key', 'variable_value');
var variable_key = pm.variables.get('variable_key');// 获取临时变量
pm.variables.unset('variable_key');// unset 临时变量// 将对象或数组(非字符串)写入环境变量
var array = [1, 2, 3, 4];
pm.environment.set('array', JSON.stringify(array));
var obj = { a: [1, 2, 3, 4], b: { c: 'val' } };
pm.environment.set('obj', JSON.stringify(obj));
// 转换回来
try {var array = JSON.parse(pm.environment.get('array'));var obj = JSON.parse(pm.environment.get('obj'));
} catch (e) {// 处理异常
}
2)前置读取/修改接口信息:
// ================= URL ===================
// 获取 url 对象
var urlObject = pm.request.url;// 获取完整接口请求 URL,包含 query 参数
var url = urlObj.toString();// 获取协议(http 或 https)
var protocol = urlObj.protocol;// 获取 端口
var port = urlObj.port;// ================= Header ===================
// 获取 Header 参数对象
var headers = pm.request.headers;// 获取 key 为 field1 的 header 参数的值
var field1 = headers.get('field1');// 已键值对象方式获取所有 query 参数
var headersObject = headers.toObject();// 遍历整个 query
headers.each(item => {console.log(item.key); // 输出参数名console.log(item.value); // 输出参数值
});// 增加 header 参数
headers.add({key: 'field1',value: 'value1',
});// 修改 query 参数(如不存在则新增)
headers.upsert({key: 'field2',value: 'value2',
});// ================= Query ===================
// 获取 Query 参数对象
var queryParams = pm.request.url.query;// 获取 key 为 field1 的 query 参数的值
var field1 = queryParams.get('field1');// 已键值对象方式获取所有 query 参数
var quertParamsObject = queryParams.toObject();// 遍历整个 query
queryParams.each(item => {console.log(item.key); // 输出参数名console.log(item.value); // 输出参数值
});// 增加 query 参数
queryParams.add({key: 'field1',value: 'value1',
});// 修改 query 参数(如不存在则新增)
queryParams.upsert({key: 'field2',value: 'value2',
});// ================= Body ===================
// Body 参数来自pm.request.body,pm.request.body 是一个RequestBody 实例。
// Body 参数在只能读取,不能直接修改。如需修改 Body 里的数据,请在 Body 里引用变量,然后在脚本里设置变量的值,以达到修改的目的。// --------------------- body 类型为 form-data ------------------
// 当 body 类型为 form-data 时,从 pm.request.body.formdata 获取请求参数
var formData = pm.request.body.formdata;// 获取 key 为 field1 的 form-data 参数的值
var field1 = formData.get('field1');
console.log(field1); // 控制台打印 field1// 已键值对象方式获取所有 formdata 参数
var formdataObject = formData.toObject();
console.log(formdataObject); // 控制台打印 formdataObject// 遍历整个 form-data 数据
formData.each(item => {console.log(item.key); // 控制台打印参数名console.log(item.value); // 控制台打印参数值
});// --------------------- body 类型为 x-www-form-urlencode ------------------
// 当 body 类型为 x-www-form-urlencode** 时,从 pm.request.body.urlencoded 获取请求参数
var formData = pm.request.body.urlencoded;// 获取 key 为 field1 的 form-data 参数的值
var field1 = formData.get('field1');// 已键值对象方式获取所有 formdata 参数
var formdataObject = formData.toObject();// 遍历整个 form 数据
formData.each(item => {console.log(item.key); // 控制台打印参数名console.log(item.value); // 控制台打印参数值
});// --------------------- body 类型为 JSON ------------------
try {var jsonData = JSON.parse(pm.request.body.raw);console.log(jsonData); // 控制台打印参整个 json 数据
} catch (e) {console.log(e);
}// --------------------- body 类型为 raw ------------------
var raw = pm.request.body.raw;
console.log(raw); // 控制台打印参整个 raw 数据
3)常用后置脚本:
pm.test("响应状态码为200", function () {pm.response.to.have.status(200);pm.expect(pm.response.code).to.eql(200);
});// GET https://gank.io/api/v2/banners
pm.test("成功响应且有数据", function() {pm.expect(pm.response.code).to.eql(200);const respJson = pm.response.json();pm.expect(respJson.data).to.length.gt(0);
})// GET https://gank.io/api/v2/data/category/GanHuo/type/iOS/page/1/count/10
pm.test("分页数据满页", function() {const respJson = pm.response.json();pm.expect(respJson.data.length).to.eq(10);pm.expect(respJson.data).to.have.lengthOf(10);
})// 在脚本中发送请求
pm.sendRequest("https://gank.io/api/v2/banners", function(err, resp) {console.log(resp.json())
})// 响应数据转换
// json
const responseJson = pm.response.json();
// xml
const responseJson = xml2Json(pm.response.text());
// csv
const parse = require('csv-parse/lib/sync');
const responseJson = parse(pm.response.text());
// html https://cheerio.js.org
const $ = cheerio.load(pm.response.text());
console.log($.html());
console.log($(".header"));
// 纯文本
pm.expect(pm.response.text()).to.include("customer_id");
pm.response.to.have.body("whole-body-text");// 将 jsonData.token 的值写入环境变量
pm.environment.set('token', jsonData.token);
4)常用断言:
// response assertions 示例
pm.test('返回结果没有错误', function() {pm.response.to.not.be.error;pm.response.to.have.jsonBody('');pm.response.to.not.have.jsonBody('error');
});// pm.response.to.be* 示例
pm.test('返回结果没有错', function() {// assert that the status code is 200pm.response.to.be.ok; // info, success, redirection, clientError, serverError, are other variants// assert that the response has a valid JSON bodypm.response.to.be.withBody;pm.response.to.be.json; // this assertion also checks if a body exists, so the above check is not needed
});// ----------- 状态码 -------------
pm.test('Status code is 200', function() {pm.response.to.have.status(200);
});
// 检查 HTTP 状态码名称是否包含某个字符串
pm.test('Status code name has string', function() {pm.response.to.have.status('Created');
});
// 是否正确的 POST 请求状态码
pm.test('Successful POST request', function() {pm.expect(pm.response.code).to.be.oneOf([201, 202]);
});// --------- 请求头 ---------
pm.expect(pm.response.headers.get('Content-Type')).to.eql('application/json');
pm.test('Content-Type header is present', function() {pm.response.to.have.header('Content-Type');
});// --------- cookie ---------
pm.expect(pm.cookies.has('JSESSIONID')).to.be.true;
pm.expect(pm.cookies.get('isLoggedIn')).to.eql('1');// --------- 响应时间 ms ---------
pm.test('Response time is less than 200ms', function() {pm.expect(pm.response.responseTime).to.be.below(200);
});// --------------- 请求体验证 -----------------
const jsonData = pm.response.json();
pm.expect(jsonData.name).to.eql("Jane");
// 响应值等于某个预先定义的变量值
pm.expect(jsonData.name).to.eql(pm.environment.get("name"));// 检查 response body 是否包含某个字符串
pm.test('Body matches string', function() {pm.expect(pm.response.text()).to.include('string_you_want_to_search');
});// 检查 response body 是否包含等于字符串
pm.test('Body is correct', function() {pm.response.to.have.body('response_body_string');
});// 检查 json 值
pm.test('Your test name', function() {var jsonData = pm.response.json();pm.expect(jsonData.value).to.eql(100);
});// 断言数据类型
pm.expect(jsonData).to.be.an("object");
pm.expect(jsonData.name).to.be.a("string");
pm.expect(jsonData.age).to.be.a("number");
pm.expect(jsonData.hobbies).to.be.an("array");
pm.expect(jsonData.website).to.be.undefined;
pm.expect(jsonData.email).to.be.null;// 数组属性
pm.expect(jsonData.errors).to.be.empty;
pm.expect(jsonData.errors).to.be.an('array').that.is.empty;
pm.expect(jsonData.areas).to.include("goods");
const contactSettings = jsonData.settings.find(m => m.type === "contact");
pm.expect(contactSettings).to.be.an("object", "找不到联系方式配置信息");
pm.expect(contactSettings.detail).to.have.members(["email", "sms"]);// 对象
pm.expect({a: 1, b: 2}).to.have.all.keys('a', 'b');
pm.expect({a: 1, b: 2}).to.have.any.keys('a', 'b');
pm.expect({a: 1, b: 2}).to.not.have.any.keys('c', 'd');
pm.expect({a: 1}).to.have.property('a');
pm.expect({a: 1, b: 2}).to.be.an('object').that.has.all.keys('a', 'b');
pm.expect({a: 1, b: 2}).to.deep.include({a:1}); // 包含部分属性
// 集合
pm.expect({"a": 1, "b": 123}.a).to.be.oneOf([1, 123]);// 字符串
pm.expect('').to.be.empty;
5)脚本里发送请求:
pm.sendRequest('https://postman-echo.com/get', (error, response) => {if (error) {console.log(error);} else {console.log(response);pm.environment.set('variable_key', 'new_value');}
});// 完整的 request 参数示例
const echoPostRequest = {url: 'https://postman-echo.com/post',method: 'POST',header: {headername1: 'value1',headername2: 'value2',},body: {mode: 'raw',raw: JSON.stringify({ key: 'this is json' }),},
};
pm.sendRequest(echoPostRequest, function(err, res) {console.log(err ? err : res.json());
});// 对返回结果进行断言
pm.sendRequest('https://postman-echo.com/get', function(err, res) {if (err) {console.log(err);}pm.test('response should be okay to process', function() {pm.expect(err).to.equal(null);pm.expect(res).to.have.property('code', 200);pm.expect(res).to.have.property('status', 'OK');});
});
在Runner中运行collection下的请求时, 可以通过postman.setNextRequest(请求名) 或者 postman.setNextRequest(请求id)来指定下一个请求, 这样可以构建起一个调用工作流, 比如先请求数据列表接口, 然后从响应中获取数据id, 再请求数据详情接口.
原文:postman | Tonny's Blog
相关文章:

postman变量和脚本功能介绍
1、基本概念——global、collection、environment 在postman中,为了更好的管理各类变量、测试环境以及脚本等,创建了一些概念,包括:globals、collection、environment。其实在postman中,最上层还有一个Workspaces的概…...

【AI新领域应用】AlphaFold 2,原子级别精度的蛋白质3D结构预测,李沐论文精读(2021Nature封面,2024诺贝尔奖)
文章目录 AlphaFold 2 —— 原子级别精度的蛋白质3D结构预测背景(2024诺奖与AI学习资料)1、摘要、导论、写作技巧2、方案:模型,编码器,解码器3、实验:数据集,训练,结果 AlphaFold 2 …...

Figma汉化:提升设计效率,降低沟通成本
在UI设计领域,Figma因其强大的功能而广受欢迎,但全英文界面对于国内设计师来说是一个不小的挑战。幸运的是,通过Figma汉化插件,我们可以克服语言障碍。以下是两种获取和安装Figma汉化插件的方法,旨在帮助国内的UI设计师…...

前端知识点---this的用法 , this动态绑定(Javascript)
文章目录 this动态绑定 , this的用法01. 全局作用域下的 this02. 函数中的 this2.1 普通函数调用2.2 构造函数调用2.3 箭头函数中的 this 03对象方法调用04. 事件处理中的 this05. 动态绑定的方式5.1 call 方法5.2 apply 方法5.3 bind 方法 06类中的 this07. 总结 this动态绑定…...

web——upload-labs——第五关——大小写绕过绕过
先上传一个 先尝试直接上传一个普通的一句话木马 不行 可以看到,.htaccess文件也被过滤了,我们来查看一下源码 第五关的源码没有把字符强制转换为小写的语句: $file_ext strtolower($file_ext); //转换为小写 直接通过Burpsuite抓包修改文…...

String类型
String类 在Java中,String 类是一个非常核心且常用的类,它用于表示文本值,即字符序列或者说字符串。 1.1 类的声明 public final class Stringimplements java.io.Serializable, Comparable<String>, CharSequence 解释:…...

Ubuntu24.04安装和配置Redis7.4
Ubuntu24.04安装和配置Redis7.4 #切换到root用户 sudo su -#更新源 apt update apt upgrade#安装 lsb-release、curl 和 gpg ,以便能够添加 Redis 仓库 apt install lsb-release curl gpg#导入 Redis 的 GPG 密钥 curl -fsSL https://packages.redis.io/gpg | gpg …...

权限相关知识
1.Linux权限的概念 在说Linux权限的概念之前我来问大家一个问题,你们觉得什么是权限? 权限平时的体现呢,就比如不是校长的亲戚就不能逛办公室,没充会员的爱奇艺看不了VIP影视剧,没成会员的的蛋糕店拿不到会员价等等等…...

【时间之外】IT人求职和创业应知【37】-AIGC私有化
目录 新闻一:2024智媒体50人成都会议暨每经20周年财经媒体峰会召开 新闻二:全球机器学习技术大会在北京召开 新闻三:区块链技术在金融领域的应用取得新突破 不知不觉的坚持了1个月,按照心理学概念,还要坚持2个月&am…...

深入理解 source 和 sh、bash 的区别
1 引言 在日常使用 Linux 的过程中,脚本的执行是不可避免的需求之一,而 source、sh、bash 等命令则是执行脚本的常用方式。尽管这些命令都能运行脚本,但它们之间的执行方式和效果却有着显著的区别。这些区别可能会影响到脚本的环境变量、工作…...

k8clone二进制工具迁移k8s中的无状态应用
1 概述 k8clone是一个简便的Kubernetes元数据克隆工具,它可以将Kubernetes元数据(对象)保存为本地压缩包,在恢复时可将这些元数据恢复到目标集群中(已存在的资源不会被覆盖)。它不依赖远程存储,…...

VPI photonics的一些使用经验(测相位 快速搜索)持续更新
1.使用FuncSinEl模块的注意事项: 2.在VPI player(示波器)测电信号相位时候,可以使用正则表达式,快速搜索。 比如我要搜索以30开头的数据,输入: ^30 其他的正则表达式不适用,比如以…...

DBeaver 连接 OceanBase Oracle 租户
DBeaver 是一款通用的数据库工具软件,支持任何具有JDBC驱动程序的数据库。DBeaver 需要 Java 运行环境的支持。截稿时 DBeaver 24.0.0 版本默认提供的 OceanBase 驱动是连接 MySQL 的,想连接 Oracle 租户需要新建一个驱动器使用。 下载数据库驱动包 1、…...

QT_CONFIG宏使用
时常在Qt代码中看到QT_CONFIG宏,之前以为和#define、DEFINES 差不多,看了定义才发现不是那么回事,定义如下: 看注释就知道了QT_CONFIG宏,其实是:实现了一个在编译时期安全检查,检查指定的Qt特性…...

力扣(leetcode)题目总结——辅助栈篇
leetcode 经典题分类 链表数组字符串哈希表二分法双指针滑动窗口递归/回溯动态规划二叉树辅助栈 本系列专栏:点击进入 leetcode题目分类 关注走一波 前言:本系列文章初衷是为了按类别整理出力扣(leetcode)最经典题目,…...

如何处理 iOS 客户端内 Webview H5 中后台播放的音视频问题
目录 问题描述Page Visibility API 的应用什么是 Page Visibility API?使用 Page Visibility API 暂停音视频完整解决方案1. 监听媒体的播放和暂停事件2. 防止自动播放3. 结合 Intersection Observer 进行媒体控制4. 手动处理应用生命周期中的事件 问题描述 在 iOS…...

C++的一些模版
1、不限制次数的输入数据 vector<int> nums;int num;while (cin >> num) {nums.push_back(num);if (cin.get() \n) break;}2、取模模版 template<int kcz> struct ModInt { #define T (*this)int x;ModInt() : x(0) {}ModInt(int y) : x(y > 0 ? y : y…...

spring boot整合https协议
整体目录 1. 生成SSL证书 首先,使用keytool生成一个自签名证书。打开命令行工具并运行以下命令: keytool -genkeypair -alias myserver -keyalg RSA -keysize 2048 -keystore keystore.jks -validity 365 这将创建一个名为keystore.jks的文件…...

服务器开机即占用大量内存,解决
1.服务器开机两分钟不到,内存使用飙升 [rootlocalhost ~]# top #查看是否有了明显的内存占用程序 2.上述未果,查看是否有违规的开机自启项 [rootlocalhost ~]# chkconfig --list 3.上述无果,查看开启启动加载项内容 上网搜后ÿ…...

Keil uvision的edition
0 Preface/Foreword 0.1 参考网址 https://zhuanlan.zhihu.com/p/456069876 1 Keil版本介绍 版本介绍: Keil Lite(免费版):最多32KB代码,无法使用中间件Keil Essential(基础版):没…...

[每周一更]-(第123期):模拟面试|消息队列面试思路解析
文章目录 22|消息队列:消息队列可以用来解决什么问题?1. 你用过消息队列吗?主要用来解决什么问题?异步、削峰和解耦你能各举一个例子吗?2. 你用的是哪个消息队列?为什么使用它而不用别的消息队列?3. 为什么你一定要用消息队列?不用行不行?不用有什么缺点?4. 在对接多…...

游戏引擎学习第12天
视频参考:https://www.bilibili.com/video/BV1yom9YnEWY 这节没讲什么东西,主要是改了一下音频的代码 后面有介绍一些alloc 和malloc,VirtualAlloc 的东西 _alloca 函数(或 alloca)分配的是栈内存,它的特点是: 生命周…...

深入理解Flutter生命周期函数之StatefulWidget(一)
目录 前言 1.为什么需要生命周期函数 2.开发过程中常用的生命周期函数 1.initState() 2.didChangeDependencies() 3.build() 4.didUpdateWidget() 5.setState() 6.deactivate() 7.dispose() 3.Flutter生命周期总结 1.调用顺序 2.函数调用时机以及主要作用 4.生…...

413: Quick Sort
解法: #include <bits/stdc.h> using namespace std; const int N1e55; int a[N]; int n;int main(int argc, char** argv) {cin>>n;for (int i0;i<n;i) cin>>a[i];sort(a,an);for (int i0;i<n;i) cout<<a[i]<<" "…...

vue之axios根据某个接口创建实例,并设置headers和超时时间,捕捉异常
import axiosNew from axios;//给axios起个别名//创建常量实例 const instanceNew axiosNew.create({//axios中请求配置有baseURL选项,表示请求URL的公共部分,url baseUrl requestUrlbaseURL: baseURL,//设置超时时间为20秒timeout: 20000,headers: {…...

Pandas数据透视表:交叉分析与聚合计算
大家好,在数据分析中,数据透视表(Pivot Table)是一种强大的工具,用于交叉分析和聚合计算。Pandas库中的数据透视表功能,使我们能够在多维数据中快速生成汇总表、统计特定维度的聚合数据,帮助揭示…...

软件设计师考试大纲
文章目录 一 、考 试 说 明1. 考试目标2. 考试要求3. 考试科目设置 二、考 试 范 围考试科目1:计算机与软件工程知识1. 计算机系统基础知识1.1计算机内数据的表示及运算1.2 其他数学基础知识1.3 计算机硬件基础知识1.3.1 计算机系统的组成、体系结构分类及特性1.3.2 存储系统1.…...

一文说清C++类型转换操作符(cast operator)
一 前言 大家在编程时,一定会遇到要做类型转换的应用场景。 但是,C风格的类型转换太强大,太危险,它允许将一个给定类型转换成我们想要的任何其他类型。 所以在C中,提供了一些更安全和更明确的类型转换操作符ÿ…...

MOSFET电路栅源极GS之间并联电容后,MOS炸管原因分析
1、前言 在介绍,在进行MOSFET相关的电路设计时,可能会遇到MOSFET误导通的问题,为了解决此问题,我们提出了两种方法,一种是增大MOSFET栅极串联电阻的阻值,另外一种是在MOSFET栅-源极之间并联一个电容&#…...

gitHub常用操作
gitHub常用操作 1、把项目拉下来2、添加上游仓库3、进入分支4、从上游仓库拉取更新 1、把项目拉下来 在对应项目的右上角点击fork,fork下来:将远程仓库复制到个人仓库 在创建好的分支文件夹下使用 git clone自己远程仓库下的http地址(fork…...