
在使用wiremock进行api模拟或录制时,开发者可能会遇到一个令人困惑的问题:当期望从第三方服务获取json响应时,wiremock却返回一个html页面,其中包含“we're sorry but isp-portal doesn't work properly without javascript enabled. please enable it to continue.”的提示。这种现象表明wiremock可能未能正确代理到api接口,而是指向了需要浏览器渲染的web前端页面。
问题描述与复现
通常,此问题发生在以下操作流程中:
-
直接调用第三方API: 首先,直接向目标第三方API发送请求,验证其返回预期的JSON响应。
curl -X GET "http://thrdpary.service.com/api/v2/requests/6396ff4eae78da7b0457f283" \ -H "authorization: Bearer mytoken" \ -H "accept: application/json"
此步骤应成功获取JSON数据。
-
启动WireMock代理: 接着,以代理模式启动WireMock,尝试将所有请求转发到第三方服务。
java -jar ~/tools/wiremock/wiremock-jre8-standalone-2.35.0.jar --print-all-network-traffic \ --verbose \ --proxy-all https://thrdpary.service.com
这里的关键是--proxy-all https://thrdpary.service.com,它指定了WireMock要代理的目标主机。
-
通过WireMock代理调用API: 最后,通过WireMock的本地端口(默认8080)发送相同的API请求。
curl -X GET "http://127.0.0.1:8080/api/v2/requests/6396ff4eae78da7b0457f283" \ -H "authorization: Bearer mytoken" \ -H "accept: application/json" -H "Content-Type: application/json"
此时,预期的JSON响应并未出现,取而代之的是一个HTML页面,内容如:
立即学习“前端免费学习笔记(深入)”;
<html lang="en"><head>...</head><body><noscript><strong>We're sorry but isp-portal doesn't work properly without JavaScript enabled. Please enable it to continue.</strong></noscript><div id="app"></div>...</body></html>
WireMock的日志也会显示代理请求返回的Content-Type是text/html,而非application/json。
根本原因分析
出现此问题的原因在于WireMock的--proxy-all参数配置不当。在上述示例中,https://thrdpary.service.com可能是一个Web前端门户的域名,而非专门用于API交互的子域名或路径。许多现代Web应用采用前后端分离架构,前端应用(如Vue.js、React等)通常部署在一个主域名下,并通过JavaScript动态加载内容,而后端API则可能部署在不同的子域名(如api.thrdpary.service.com)或特定的路径下。
当WireMock代理到Web前端门户时,它接收到的就是前端应用的HTML骨架,其中包含提示需要JavaScript才能正常工作的<noscript>标签内容。由于curl命令是一个命令行工具,它不会执行JavaScript,因此无法渲染前端页面,只能显示原始HTML,导致用户看到“JavaScript未启用”的错误信息。
解决方案
解决此问题的核心在于将WireMock的--proxy-all参数指向正确的API端点,而非Web门户。这通常意味着需要识别并使用API专用的子域名或更精确的路径。
在上述案例中,如果第三方服务的API位于api.thrdpary.service.com这个子域名下,那么正确的WireMock启动命令应该是:
java -jar ~/tools/wiremock/wiremock-jre8-standalone-2.35.0.jar --print-all-network-traffic \ --verbose \ --proxy-all https://api.thrdpary.service.com
通过将--proxy-all的目标从https://thrdpary.service.com更改为https://api.thrdpary.service.com,WireMock将直接代理到API服务,从而能够捕获并返回正确的JSON响应。
注意事项
- 区分Web门户与API端点:在配置WireMock代理时,务必仔细检查目标服务的文档,明确其API的实际基础URL。API通常会有api.开头的子域名,或者特定的路径前缀(如/api/v1)。
- HTTP与HTTPS代理:WireMock在本地机器上可以灵活地将本地HTTP请求代理到远程的HTTPS服务。这意味着即使你的WireMock客户端通过HTTP(http://127.0.0.1:8080)发送请求,WireMock也能成功将其转发到远程的HTTPS目标。
- 详细日志分析:当遇到问题时,--print-all-network-traffic和--verbose参数非常有用,它们可以打印出WireMock代理过程中所有的请求和响应详情,包括HTTP头和响应体,这有助于识别Content-Type是否正确,以及响应内容是否为预期的JSON。
- 录制模式:如果目的是录制API交互,确保WireMock处于录制模式,并且其代理目标是正确的API端点。
总结
当WireMock代理返回“JavaScript未启用”的HTML响应而非预期的JSON时,根本原因在于--proxy-all参数指向了需要浏览器渲染的Web前端页面,而非实际的API服务。解决办法是精确地将WireMock配置为代理API专用的域名或路径。通过仔细核对目标服务的API文档并正确配置WireMock,可以确保API模拟和录制过程的顺利进行。











