非常游戏网
如何在Flask中集成百度地图API_通过Python后端转发请求处理跨域

如何在Flask中集成百度地图API_通过Python后端转发请求处理跨域

2026-05-28日常编程274078

前端不能直接调用百度地图API,因为AK必须绑定域名白名单,写在前端会暴露密钥导致盗用、配额超限或封禁;后端转发核心是保护密钥,而非绕过跨域,所有带AK的接口均需服务端中转。

为什么不能让前端直接调用百度地图API

因为百度地图JavaScript API强制要求使用ak(Access Key)且该密钥**仅限绑定域名白名单**,而一旦把ak写在前端代码里,就等于公开暴露——别人抓包就能盗用,触发配额超限或被封禁。后端转发的核心目的不是“绕过跨域”,而是“保护密钥”。

  • 前端直连百度接口会返回 401 UnauthorizedINVALID_REQUEST 错误,日志里常带 refuse by ak
  • 百度不支持CORS,所以浏览器会拦截响应(即使HTTP状态码是200)
  • 所有需携带ak的接口(如/geocoding/v3//place/v2/search)都必须走服务端中转

Flask路由如何安全转发百度API请求

关键点在于:只透传必要参数,不暴露原始ak,并过滤掉可能被滥用的字段(比如callbackoutput)。用requests发GET请求时,把ak拼进URL,但禁止用户输入ak

  • os.getenv("BAIDU_AK")从环境变量读取密钥,绝不在代码里硬编码
  • 对用户传入的queryregion等参数做白名单校验,例如限制region只能是中文城市名或全国
  • 强制指定output=json,忽略前端传来的output参数,防止JSONP注入
  • 示例路由:
    @app.route("/api/baidu/geocode")
    def baidu_geocode():
    query = request.args.get("address")
    if not query or len(query) > 100:
    return {"error": "invalid address"}, 400
    params = {
    "address": query,
    "city": request.args.get("city", ""),
    "output": "json",
    "ak": os.getenv("BAIDU_AK")
    }
    resp = requests.get("https://api.map.baidu.com/geocoding/v3/", params=params)
    return resp.json(), resp.status_code

如何避免Flask转发时丢失HTTP头或状态码

百度API返回的Content-Typeapplication/json;charset=UTF-8,但Flask默认用text/html响应;另外,百度可能返回400500错误码,如果只用resp.json()会丢掉原始状态码,导致前端无法区分“地址不存在”和“服务不可用”。

Python 3.14.3

微软官方的 Python 扩展,是 VS Code 安装量最高的扩展(209M+)。集成 IntelliSense(通过 Pylance)、调试(通过 Python Debugger)、代码检查、格式化、重构和单元测试等功能。支持 Jupyter Notebook、虚拟环境管理和多 Python 版本切换。

  • 必须显式返回resp.status_code,否则全是200
  • Response(resp.content, status=resp.status_code, mimetype=resp.headers.get("Content-Type"))完整透传响应体和头
  • 特别注意:resp.json()在百度返回非JSON(如HTML错误页)时会抛JSONDecodeError,应捕获并记录日志
  • 不要用jsonify()包装百度响应——它会强制设Content-Type: application/json,覆盖百度原头

本地开发时如何调试转发链路

常见卡点是:本地Flask跑在http://localhost:5000,但百度AK绑定了https://myapp.com,导致测试时一直refuse by ak。这不是跨域问题,是AK域名不匹配。

  • 百度控制台为开发环境单独申请一个测试用ak,绑定localhost127.0.0.1(注意端口不用填)
  • curl -v http://localhost:5000/api/baidu/geocode?address=北京站直测Flask路由,看是否返回百度原始JSON
  • 在Flask中加app.logger.info(f"Forwarding to Baidu: {url}"),确认拼出的URL含正确ak且无多余参数
  • 如果百度返回{"status":3,"message":"APP NOT AUTHORIZED"},99%是ak没生效或域名未备案

百度API转发本身不复杂,真正容易翻车的是密钥管理粒度和错误透传完整性——漏掉一个状态码或错判一次ak绑定范围,前端就只剩黑盒报错。