一、基础概念
1.1 什么是Pre-request Script?
-
在发送请求之前自动执行的JavaScript代码
-
执行时机:在请求发送到服务器之前
-
主要用途:准备请求数据、设置环境变量、生成签名等
1.2 基本结构
// 示例:简单的pre-request脚本
pm.environment.set("timestamp", Date.now());
console.log("请求即将发送:", pm.request.url.toString());
二、核心功能详解
2.1 变量操作
// 设置环境变量
pm.environment.set("api_key", "your-api-key-123");
pm.environment.set("timestamp", new Date().getTime());
// 设置全局变量
pm.globals.set("base_url", "https://api.example.com");
// 设置集合变量
pm.collectionVariables.set("version", "v1");
// 获取变量
let token = pm.environment.get("access_token");
let baseUrl = pm.globals.get("base_url");
// 取消设置变量
pm.environment.unset("temp_token");
2.2 请求修改
// 修改请求头
pm.request.headers.add({
key: "X-Custom-Header",
value: "custom-value"
});
// 修改URL参数
const url = new URL(pm.request.url.toString());
url.searchParams.set("timestamp", Date.now());
pm.request.url = url.toString();
// 修改请求体(仅适用于raw body)
if (pm.request.body && pm.request.body.mode === "raw") {
const rawBody = JSON.parse(pm.request.body.raw);
rawBody.timestamp = new Date().toISOString();
pm.request.body.raw = JSON.stringify(rawBody);
}
2.3 条件逻辑
// 根据环境执行不同操作
const env = pm.environment.get("env");
if (env === "production") {
pm.request.headers.add({
key: "Authorization",
value: "Bearer " + pm.environment.get("prod_token")
});
} else {
pm.request.headers.add({
key: "Authorization",
value: "Bearer " + pm.environment.get("dev_token")
});
}
三、高级"骚操作"
3.1 动态签名生成
// HMAC SHA256签名示例
const CryptoJS = require("crypto-js");
function generateSignature(secret, method, path, body, timestamp) {
const stringToSign = `${method}\n${path}\n${timestamp}\n${body}`;
return CryptoJS.HmacSHA256(stringToSign, secret).toString(CryptoJS.enc.Hex);
}
// 使用示例
const secret = pm.environment.get("api_secret");
const method = pm.request.method;
const path = new URL(pm.request.url.toString()).pathname;
const body = pm.request.body?.raw || "";
const timestamp = Date.now();
const signature = generateSignature(secret, method, path, body, timestamp);
pm.request.headers.add({
key: "X-Signature",
value: signature
});
pm.request.headers.add({
key: "X-Timestamp",
value: timestamp.toString()
});
3.2 请求链与依赖处理
// 获取前一个请求的响应数据
const previousResponse = pm.getGlobal("previous_response");
if (previousResponse) {
const data = JSON.parse(previousResponse);
pm.environment.set("session_id", data.session_id);
}
// 设置本次请求完成后的回调
pm.sendRequest({
url: "https://auth.example.com/token",
method: "POST",
header: { "Content-Type": "application/json" },
body: {
mode: "raw",
raw: JSON.stringify({
grant_type: "client_credentials",
client_id: pm.environment.get("client_id"),
client_secret: pm.environment.get("client_secret")
})
}
}, function (err, response) {
if (!err) {
const token = response.json().access_token;
pm.environment.set("access_token", token);
// 继续发送主请求
pm.request.headers.add({
key: "Authorization",
value: `Bearer ${token}`
});
}
});
3.3 数据加密
// AES加密示例
const CryptoJS = require("crypto-js");
function encryptData(data, key) {
const encrypted = CryptoJS.AES.encrypt(
JSON.stringify(data),
key
).toString();
return encrypted;
}
// 加密请求体
const requestBody = {
data: "sensitive information",
timestamp: new Date().toISOString()
};
const encryptedBody = encryptData(
requestBody,
pm.environment.get("encryption_key")
);
pm.request.body = {
mode: "raw",
raw: JSON.stringify({ payload: encryptedBody })
};
3.4 随机数据生成
// 生成随机数据
function generateRandomString(length) {
const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
let result = '';
for (let i = 0; i < length; i++) {
result += chars.charAt(Math.floor(Math.random() * chars.length));
}
return result;
}
function generateRandomEmail() {
return `test${Date.now()}@example.com`;
}
// 使用示例
pm.environment.set("random_email", generateRandomEmail());
pm.environment.set("order_id", `ORD${Date.now()}${Math.floor(Math.random() * 1000)}`);
3.5 性能测试相关
// 记录请求开始时间
pm.environment.set("request_start_time", Date.now());
// 在Tests脚本中计算耗时
// Tests脚本中可以这样计算:
// const startTime = pm.environment.get("request_start_time");
// const endTime = Date.now();
// console.log(`请求耗时: ${endTime - startTime}ms`);
3.6 工作流控制
// 条件跳过请求
const skipRequest = pm.environment.get("skip_request");
if (skipRequest === "true") {
// 设置请求为不发送
pm.request.headers.add({
key: "X-Skip-Request",
value: "true"
});
// 或者通过抛出错误停止
// throw new Error("跳过此请求");
}
// 最大重试次数控制
let retryCount = pm.environment.get("retry_count") || 0;
if (retryCount >= 3) {
throw new Error("已达到最大重试次数");
}
pm.environment.set("retry_count", retryCount + 1);
3.7 文件操作模拟
// 模拟文件上传
const fileContent = "This is a test file content";
const fileName = `test_${Date.now()}.txt`;
// 创建FormData
const formdata = new FormData();
formdata.append("file", new Blob([fileContent]), fileName);
formdata.append("description", "Test file upload");
// 注意:Postman中文件上传通常通过界面操作
// 这里主要展示如何生成相关数据
3.8 缓存控制
// 生成ETag
function generateETag(data) {
const CryptoJS = require("crypto-js");
return CryptoJS.MD5(JSON.stringify(data)).toString();
}
// 检查缓存
const cachedData = pm.environment.get("cached_data");
const cacheKey = pm.environment.get("cache_key");
if (cachedData && cacheKey === pm.request.url.toString()) {
// 设置If-None-Match头
pm.request.headers.add({
key: "If-None-Match",
value: generateETag(cachedData)
});
}
四、实用技巧
4.1 调试技巧
// 使用console.log调试
console.log("当前环境:", pm.environment.name);
console.log("请求URL:", pm.request.url.toString());
console.log("请求方法:", pm.request.method);
console.log("所有头信息:", pm.request.headers);
// 使用try-catch捕获错误
try {
// 可能出错的代码
const data = JSON.parse(pm.environment.get("config"));
} catch (error) {
console.error("解析配置出错:", error.message);
// 设置默认值
pm.environment.set("config", "{}");
}
4.2 性能优化
// 避免重复计算
if (!pm.environment.get("cached_timestamp")) {
const timestamp = Date.now();
pm.environment.set("cached_timestamp", timestamp);
pm.environment.set("cached_timestamp_expiry", timestamp + 5000); // 5秒缓存
}
4.3 最佳实践
// 1. 使用函数组织代码
function setupAuth() {
// 认证逻辑
}
function addCommonHeaders() {
// 添加公共头
}
function validateRequest() {
// 请求验证
}
// 2. 模块化执行
setupAuth();
addCommonHeaders();
validateRequest();
// 3. 清理临时变量
pm.environment.unset("temp_variable");
五、注意事项
-
执行顺序:Pre-request Script在每次请求前都会运行
-
性能影响:复杂脚本可能延迟请求发送
-
错误处理:脚本错误会导致请求失败
-
变量作用域:注意环境变量、全局变量的区别
-
安全性:不要在脚本中硬编码敏感信息
六、实际应用场景
-
API签名认证:自动生成签名
-
数据准备:生成测试数据
-
请求转换:修改请求格式
-
条件测试:根据不同场景设置不同参数
-
工作流管理:控制请求执行顺序
-
性能监控:记录请求时间戳
-
缓存管理:实现客户端缓存逻辑
这些高级技巧可以大大提升Postman的自动化测试能力,特别是在复杂的API测试场景中。