Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

URL一样的的Post请求,想根据reqBody里的不同参数,返回不同的resBody #39

Open
shownstrong opened this issue Jul 24, 2024 · 7 comments

Comments

@shownstrong
Copy link

1.目前普通用法配置规则resBody://{reponse1}, 由于post请求的url都是一致的,每次mock不同数据需要临时重新修改。
不知道是否能定义规则,根据不同的reqBody,返回不同的resBody。一次性配置好,不需要临时再修改

2.尝试过whistle.script://test

 exports.handleRequestRules = (ctx) => {
 	// ctx.fullUrl 可以获取请求url
 	// ctx.headers 可以获取请求头
 	// ctx.options 里面包含一些特殊的请求头字段,分别可以获取一些额外信息,如请求方法、设置的规则等
 	ctx.rules = ['www.qq.com file://{test.html}'];
  	ctx.values = { 'test.html': 'Hello world.' };
 };

测试过Readme文档里的test脚本,可以mock成功。但是尝试获取请求体失败。

// 获取请求体数据
const requestBody = await new Promise((resolve, reject) => {
  let data = [];
  ctx.req.on('data', chunk => {
    data.push(chunk);
  });
  ctx.req.on('end', () => {
    resolve(Buffer.concat(data));
  });
  ctx.req.on('error', err => {
    reject(err);
  });
});

// 转换请求体数据为字符串
const requestBodyString = requestBody.toString();
console.log('原始请求体数据长度:', requestBody.length);
console.log('原始请求体数据:', requestBodyString);

// 解析 JSON 格式的请求体数据
let bodyData;
if (requestBodyString) {
  try {
    bodyData = JSON.parse(requestBodyString);
  } catch (err) {
    console.error('请求体解析错误:', err);
    console.error('解析失败的请求体:', requestBodyString);
    bodyData = null;
  }
} else {
  console.log('请求体为空');
  bodyData = null;
}

js小白,麻烦大佬有空指导下

@shownstrong
Copy link
Author

Version: 2.9.74

@avwo
Copy link
Member

avwo commented Jul 24, 2024

可以通过过滤器 excludeFilter://b:patternincludeFilter://b:pattern 匹配请求内容,看下能不能满足需求:https://wproxy.org/whistle/rules/filter.html

@shownstrong
Copy link
Author

可以通过过滤器 excludeFilter://b:patternincludeFilter://b:pattern 匹配请求内容,看下能不能满足需求:https://wproxy.org/whistle/rules/filter.html

1.感谢大佬,测试通过。不过我理解这种只适合用于reqBody取1个参数来判断的情况,如果要取多个参数,就不合适了。

2.对于whistle.script://test的方式,有解析reqBody的范例或者文档吗

@avwo
Copy link
Member

avwo commented Jul 25, 2024

可用正则表达式,过滤器也可以同时设置多个

@sosohime
Copy link
Contributor

可以通过过滤器 excludeFilter://b:patternincludeFilter://b:pattern 匹配请求内容,看下能不能满足需求:https://wproxy.org/whistle/rules/filter.html

1.感谢大佬,测试通过。不过我理解这种只适合用于reqBody取1个参数来判断的情况,如果要取多个参数,就不合适了。

2.对于whistle.script://test的方式,有解析reqBody的范例或者文档吗

注意插件规则配置是script://test,不是whistle.script://test

参考

exports.handleRequest = (ctx, request) => {
	// ctx.fullUrl 可以获取请求url
	// ctx.headers 可以获取请求头
	// ctx.options 里面包含一些特殊的请求头字段,分别可以获取一些额外信息,如请设置的规则等
	// ctx.method 获取和设置请求方法
	// ctx.req
	// ctx.res
  const {req, res} = ctx;
  const client = request((svrRes) => {
    // 由于内容长度可能有变,删除长度自动改成 chunked
    delete svrRes.headers['content-length'];
    delete req.headers['accept-encoding'];
    let body;
    svrRes.on('data', (data) => {
      body = body ? Buffer.concat([body, data]) : data;
    });
    svrRes.on('end', () => {
      try {
        // 获取到服务器返回体json格式,进行你想要的处理
        const jsonBody = JSON.parse(body.toString())
        const wrappedBody = {
            code: body.code || svrRes.statusCode,
        	result: jsonBody
        }
        res.end(Buffer.from(JSON.stringify(wrappedBody)))
      } catch(e) {
        res.end(body);
      }      
    });
  });
  req.pipe(client);
};

@shownstrong
Copy link
Author

感谢2位大佬解答。我现在发现正则也够用了,我这边的场景post的reqBody有1个id参数,我只针对这个参数写正则就行

@avwo
Copy link
Member

avwo commented Sep 29, 2024

requestBody

你代码有 bug,改成这个试试

// 转换请求体数据为字符串
const requestBodyString = (await requestBody).toString();
console.log('原始请求体数据长度:', requestBody.length);
console.log('原始请求体数据:', requestBodyString);

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants