如何通过JavaScript Fetch携带查询语句请求Elastic API
解答
Elasticsearch _search 接口完全支持通过Fetch请求携带自定义查询条件,查询DSL的放置位置和所选请求方法有关,优先推荐POST传参方案,全链路兼容性最好。
方案1:POST请求携带请求体(官方推荐)
Elasticsearch官方约定复杂查询统一用POST方式发起,查询语句直接序列化为JSON字符串放在请求的body字段中,同时需要在请求头增加Content-Type: application/json标识请求体格式,避免服务端解析失败。
注意:虽然部分Elasticsearch版本兼容GET请求携带请求体的写法,但部分网关、代理层会直接丢弃GET请求的body内容,线上环境不建议使用。
修改后的可直接运行代码如下:
var url = 'http://192.168.150.155:9900/em-employeedata/_search'; async function getapi(url) { // 自定义查询DSL const queryDSL = { "size": 10000, "query": { "match_all": {} } } const response = await fetch(url, { method: 'POST', headers: { 'Authorization': 'Basic ' + btoa('em_user:3md@t@2o22'), 'Content-Type': 'application/json' }, body: JSON.stringify(queryDSL) // 查询语句序列化后传入请求体 }) // 基础错误处理 if (!response.ok) { throw new Error(`请求异常,状态码:${response.status}`) } var data = await response.json(); return data } getapi(url).then(res => { console.log('查询结果', res) }).catch(err => { console.error('请求失败', err) })
方案2:GET请求通过URL参数传递(仅适合简单查询)
如果必须使用GET请求,可以将查询DSL做URL编码后,放在URL的source查询参数中,同时携带source_content_type=application/json参数告知服务端参数内容格式。
这种方式受URL长度限制,仅适合短查询,示例写法:
const queryDSL = { "size": 10000, "query": { "match_all": {} } } // 拼接带查询参数的URL var url = `http://192.168.150.155:9900/em-employeedata/_search?source=${encodeURIComponent(JSON.stringify(queryDSL))}&source_content_type=application/json`; async function getapi(url) { const response = await fetch(url, { method: 'GET', headers: { 'Authorization': 'Basic ' + btoa('em_user:3md@t@2o22') } }) if (!response.ok) { throw new Error(`请求异常,状态码:${response.status}`) } var data = await response.json(); return data } getapi(url)
注意事项
- 原有代码中URL末尾多余的斜杠不影响接口调用,但建议和官方路径对齐,去掉末尾斜杠即可
size: 10000刚好是Elasticsearch默认的index.max_result_window阈值,如果单次需要拉取超过10000条数据,不要直接调大size参数,建议使用scroll或者search_after做分批拉取,避免服务端内存溢出- 生产环境建议为Elasticsearch开启HTTPS,避免Basic认证凭据明文传输泄露
内容的提问来源于stack exchange,提问作者Meikel Rizky Hartawan
相关产品推荐
相关产品推荐

