我看似有效的URL在本地解析,但在heroku上部署时失败了



这是我关于stackoverflow的第一个问题,所以请温柔一点。我正在使用node.js构建一个简单的应用程序,该应用程序依赖于对外部地理编码服务的API调用。我的程序在本地运行,但在部署到heroku时失败。以下是正在失败的功能:

async function geoEncode(restaurant = false, string = false) {
let address;
address = (string) ? string : require('querystring').escape(`${restaurant.street_address}, ${restaurant.city_state_zip}, ${restaurant.state}, ${restaurant.zip}`);
let url = await geoApi.replace("SEARCH_STRING", address);
let encodedURL = new URL(url);
let init = {};
let headers = {
"async": true,
"crossDomain": true,
"method": "GET",
"Host": "us1.locationiq.com",
}
init.headers = headers;
try {
let response = await fetch(encodedURL.href, init);
let output = await response.json();
return output;
} catch(err){
console.log("this log an error in geoEncode", err);
}
}

我认识到,这段代码目前充斥着不必要的编码和冗余的头。调试过程失败的副作用。当在本地运行时,程序会向服务发送一个有效的url,并返回响应数据。当部署在heroku上时,

let encodedURL = new URL(url);

投掷

TypeError [ERR_INVALID_URL]: Invalid URL: "https://us1.locationiq.com/v1/search.php?key ...

我为我的问题编辑了这个url以保护API密钥,但当我获取该字符串(减去引号(并通过浏览器运行它时,它会返回有效的JSON。

在部署之前,我根本没有对url进行任何编码——我只是构建了一个字符串,并将其提供给节点获取模块的获取方法。它在Heroku上出错,并显示消息"TypeError:仅支持绝对URL"。我后来了解到,这个错误消息意味着nodefetch的请求方法无法解析协议或主机名。我已经确定,当部署在heroku上时,它无法解析两者。

我的本地环境和heroku的明显区别在于,我通过heroku面板设置了环境变量,而不是通过.env文件。因为我有点不清楚这是如何工作的,所以我最近的大部分调试都试图确保我提供给fetch API的字符串是一致、统一的编码。因此,我预先转义了我的代码,手动utf8对其进行编码,通过URL模块运行它,并在不接触它的情况下将该URL编码的输出输入到函数中。它仍然在本地工作,但在远程失败。

我的基本堆栈是MongoDB、Express、Node、Bootstrap。我对我的云MongoDB服务器进行的调用以及对API的调用都有效,我从API获取地理代码中的数据。只有这些对我的地理编码服务的调用失败了,所以我用于MongoDB连接的环境变量按预期运行。

谢谢你的帮助!

编辑1:

在回答下面的一条评论时(对我尝试的评论回答的格式感到抱歉;我现在知道标记格式在评论中是有限的(,我发布的错误是使用命令"heroku logs--tail"从heroku记录的。我已经手动记录了我试图编码的URL(下面是一个经过编辑的例子(:

URL to be encoded: "https://us1.locationiq.com/v1/search.php?key=KEY-REDACTED&format=json&q=101%20NICKERSON%20ST%2C%20SEATTLE%2C%20WA%2C%2098109-1654"

以及heroku报告的错误:

TypeError [ERR_INVALID_URL]: Invalid URL: "https://us1.locationiq.com/v1/search.php?key=KEY-REDACTED=json&q=101%20NICKERSON%20ST%2C%20SEATTLE%2C%20WA%2C%2098109-1654"

编辑2:

我想我可能在帖子中没有提供足够的错误日志。这是一个更完整的错误日志。我希望这对那些能反过来帮助我的人有帮助

2019-11-14T23:35:09.646585+00:00 app[web.1]: (node:23) UnhandledPromiseRejectionWarning: TypeError [ERR_INVALID_URL]: Invalid URL: "https://us1.locationiq.com/v1/search.php?key=KEY_REDACTED&format=json&q=101%20NICKERSON%20ST%2C%20SEATTLE%2C%20WA%2C%2098109-1654"
2019-11-14T23:35:09.646591+00:00 app[web.1]: at onParseError (internal/url.js:243:9)
2019-11-14T23:35:09.646593+00:00 app[web.1]: at new URL (internal/url.js:319:5)
2019-11-14T23:35:09.646595+00:00 app[web.1]: at geoEncode (/app/server.js:308:20)
2019-11-14T23:35:09.646599+00:00 app[web.1]: at processTicksAndRejections (internal/process/task_queues.js:93:5)
2019-11-14T23:35:09.646602+00:00 app[web.1]: at async Timeout._onTimeout (/app/server.js:373:29)

已解决!不出所料,答案是枯燥的,但现在是:

当我在heroku面板中输入引用为geoAPI的环境变量时,我将其输入为带引号的字符串。Heroku必须已经将环境变量键入为字符串,因为结果是以"开头和结尾的字符串,这导致url模块无法解析。当我控制台记录querystring.parse(url(的输出并收到:时,我最终发现了这个问题

parsed querystring: [Object: null prototype] {
2019-11-19T21:54:59.724380+00:00 app[web.1]: '"https://us1.locationiq.com/v1/search.php?key': 'REDACTED',
2019-11-19T21:54:59.724382+00:00 app[web.1]: format: 'json',
2019-11-19T21:54:59.724385+00:00 app[web.1]: q: '101 NICKERSON ST, SEATTLE, WA, 98109-1654"' }

显然,额外的引号使第一个"="之前的所有内容都读作了一个键。这就是我发现额外报价的原因。删除多余的引号解决了问题。很高兴它结束了,但很遗憾它只是heroku面板中的一个格式错误。

我的小教训是:不要把heroku环境变量放在引号里。他们不是这样工作的。

我从中得到的重要教训是:当有什么神秘的东西时,尽早检查你的环境。如果你检查了一下,没有发现任何东西,并且在问题上停留了很长一段时间,就再检查一次。

相关内容

  • 没有找到相关文章

最新更新