BaseX HTTP客户端http:send-request() 在执行远程REST XQuery时返回“Content is not allowed in prolog”错误

后端开发 2026-07-09

我正在尝试通过 http:send-request() 和BaseX REST API,在另一台BaseX服务器上远程执行XQuery。

架构:

  • 服务器1:

  • 包含 test数据库

  • BaseX REST API运行在端口 8080
  • 服务器2:

  • 仅包含BaseX应用/代码

  • 执行管线XQuery
  • 向服务器1 发送REST请求以远程查询数据库

问题在于,对REST端点的每个POST请求都会返回以下错误:

[experr:HC0002] Conversion failed:
"" (Line 1): Content is not allowed in prolog.

或有时:

[XPST0003] Empty query.

我可以通过一个简单的GET请求成功访问REST端点:

let $DataServer := 'http://xx.xx.xx.xx:8080/rest/'
let $httpTarget := fn:concat($DataServer,'test','/data/')

let $res :=
(
  http:send-request(
    <http:request
      method='get'
      username='admin'
      password='admin'
      send-authorization='true'
      href='{$httpTarget}'
      auth-method='Basic'>
    </http:request>
  )
)[2]

return $res

这会正确返回:

<database xmlns="http://basex.org/rest" name="test">
  <dir>...</dir>
</database>

但当我尝试通过POST远程执行查询时,它失败。

示例:

declare namespace http = "http://expath.org/ns/http-client";

let $query :=
  "for $i in fn:uri-collection('bloomsbury/jobs/') return $i"

let $res :=
  http:send-request(
    <http:request
      method="post"
      href="http://xx.xxx.xxx.xxx:8080/rest"
      username="admin"
      password="admin"
      send-authorization="true">

      <http:body media-type="application/x-www-form-urlencoded">
        { "query=" || encode-for-uri($query) }
      </http:body>

    </http:request>
  )

return $res

仍然得到:

Content is not allowed in prolog

环境:

  • BaseX 11
  • REST API已启用
  • XQuery从另一台BaseX服务器执行

问题:

  1. 使用 http:send-request() 通过BaseX REST API发送XQuery的正确方法是什么?
  2. 查询应作为XML(<query><text>)发送,还是作为 application/x-www-form-urlencoded
  3. 是否存在已知的编码/BOM问题导致此问题?

任何帮助将不胜感激。

解决方案

我找到了原因。

问题在于我把查询作为 application/x-www-form-urlencoded 发送。BaseX REST对此与 http:send-request() 配合处理并不佳,最终导致请求体被错误解析,从而产生如下错误:

  • Content is not allowed in prolog
  • Empty query

有效的做法是将XQuery直接作为POST体发送:

Content-Type: application/query+xml

示例:

declare namespace http = "http://expath.org/ns/http-client";

let $query :=
  'for $i in db:list("test") return $i'

return
http:send-request(
  <http:request
      method="post"
      href="http://10.xxx.xxx.xxx:8080/rest"
      username="admin"
      password="admin"
      auth-method="Basic"
      send-authorization="true">

      <http:header
          name="Content-Type"
          value="application/query+xml"/>

      <http:body media-type="application/query+xml">
        { $query }
      </http:body>

  </http:request>
)

另外,在XQuery的 XML构造中有一个小细节很重要:

href="{ $url }"

是正确的,不是:

href='{$url}'
站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。

相关文章