TypeScript调用Overpass API遇阻求助:请求报错及代码示例
TypeScript调用Overpass API报错排查
问题描述
在TypeScript中调用Overpass API时遇到以下问题:
- ts-overpass包的唯一示例无法运行
- 找到的示例仅适用于Overpass Turbo
- 官方文档中的示例在Overpass Turbo可正常运行,但自行编写的代码调用时报错
- 能正常请求jsonplaceholder接口,但无法正常调用Overpass API
原代码
var fs = require('fs').promises; (async function () { const data = await getData() if (!data) return try { await fs.writeFile('.output/data.xml', data); } catch (error) { console.error(error); } })(); async function getData() { const query = `nwr[shop=supermarket]({{bbox}});out center;` try { const response = await fetch( 'https://maps.mail.ru/osm/tools/overpass/api/interpreter' , { method: 'POST', headers: { 'content-type': 'application/json;charset=UTF-8', }, body: JSON.stringify({ query: query, }), }) const data = await response.text() return data } catch (error) { console.log(error); } }
返回的错误响应
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> <head> <meta http-equiv="content-type" content="text/html; charset=utf-8" lang="en"/> <title>OSM3S Response</title> </head> <body> <p>The data included in this document is from www.openstreetmap.org. The data is made available under ODbL.</p> <p><strong style="color:#FF0000">Error</strong>: line 1: parse error: Unknown type "{" </p> <p><strong style="color:#FF0000">Error</strong>: line 1: parse error: An empty query is not allowed </p> <p><strong style="color:#FF0000">Error</strong>: line 1: parse error: ';' expected - '"query"' found. </p> <p><strong style="color:#FF0000">Error</strong>: line 2: parse error: Unexpected end of input. </p> </body> </html>
问题分析
从错误信息可明确问题根源:
- Overpass API不支持JSON格式的请求体,错误提示“Unknown type "{"”说明API接收到了JSON数据,但它仅能解析纯文本查询或特定参数格式的请求
- 代码中的
{{bbox}}是Overpass Turbo专属占位符,直接发送给API会导致查询失败,需替换为具体的经纬度边界框(格式:(南纬, 西经, 北纬, 东经),例如(50.0, 10.0, 50.1, 10.1))
修复方案
方案1:直接发送纯文本查询语句
修改请求头为text/plain,将查询语句作为请求体直接发送:
var fs = require('fs').promises; (async function () { const data = await getData() if (!data) return try { await fs.writeFile('.output/data.xml', data); } catch (error) { console.error(error); } })(); async function getData() { // 替换{{bbox}}为实际边界框坐标 const query = `nwr[shop=supermarket](50.0, 10.0, 50.1, 10.1);out center;` try { const response = await fetch( 'https://maps.mail.ru/osm/tools/overpass/api/interpreter', { method: 'POST', headers: { 'content-type': 'text/plain;charset=UTF-8', }, body: query, }) const data = await response.text() return data } catch (error) { console.log(error); } }
方案2:通过URLSearchParams传递data参数
这种方式更贴合Overpass API的标准调用规范:
var fs = require('fs').promises; (async function () { const data = await getData() if (!data) return try { await fs.writeFile('.output/data.xml', data); } catch (error) { console.error(error); } })(); async function getData() { // 替换{{bbox}}为实际边界框坐标 const query = `nwr[shop=supermarket](50.0, 10.0, 50.1, 10.1);out center;` try { const params = new URLSearchParams(); params.append('data', query); const response = await fetch( 'https://maps.mail.ru/osm/tools/overpass/api/interpreter', { method: 'POST', body: params, }) const data = await response.text() return data } catch (error) { console.log(error); } }
额外说明
- 使用ts-overpass包时,需确认包版本兼容性,且示例中的API端点与实际使用的一致
- 调用Overpass API时需注意请求频率限制,避免触发限流机制
内容的提问来源于stack exchange,提问作者PRR S2 6-8-6 turbine engine
相关产品推荐
相关产品推荐

