Azure Cognitive Search浏览器端上传文档CORS报错解决方案咨询
问题根因
你配置完CORS还是报错根本不是配置错了,是Azure Cognitive Search本身的设计限制:
- 服务端的CORS响应头仅对查询类的读接口生效,所有涉及文档写入、索引修改、服务配置变更的写接口,默认就不会返回
Access-Control-Allow-Origin头,不管你怎么配CORS策略都没用,就是为了防止用户直接从浏览器端调用写接口。 - 你现在把Search服务的管理密钥直接写在前端代码里是非常危险的做法,任何访问你网页的用户打开控制台就能拿到这个密钥,可以任意删除、篡改、爬取你索引里的所有数据,完全没有安全防护。
可行实现方案
你想的用无服务器函数的思路完全正确,而且你已经用了Azure Static Web App,直接用它自带的集成Azure Functions做后端接口就行,不用额外买服务,新手也能快速搭好:
- 所有和Azure Cognitive Search写操作相关的逻辑,全部放到服务端的Azure Function里执行,服务端发请求不存在浏览器跨域限制,也不会把Search的密钥暴露给前端用户。
- 前端提交新用户名的时候,不要直接请求Search服务的地址,改成请求你自己部署的Function接口,只需要把用户输入的用户名当参数传过去就行。
- Function收到前端的请求之后,从配置项里读取存在服务端的Search服务密钥,再向Search服务发起写入文档的请求,处理完成后把成功/失败的结果返回给前端即可。
参考代码
前端提交逻辑修改
把你原来直接调用Search接口的代码替换成调用自有接口的逻辑:
async OnSubmitCreate(){ console.log('Create started') // 请求自有后端接口,不传递、不暴露Search服务密钥 const response = await fetch('/api/create-user', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ username: this.createName }) }); if (response.ok) { // 这里写创建成功后的页面逻辑,比如跳转到游戏主页 alert('用户创建成功'); } else { alert('创建失败,请重试'); } }
Azure Function 后端代码(Node.js 版本)
在你的Static Web App项目里新建/api/create-user/index.js文件,写入以下逻辑:
const { SearchClient, AzureKeyCredential } = require("@azure/search-documents"); module.exports = async function (context, req) { // 校验前端传的参数 const username = req.body?.username?.trim(); if (!username) { context.res = { status: 400, body: "用户名不能为空" }; return; } try { // 初始化Search客户端,密钥从服务端配置读取,不对外暴露 const searchClient = new SearchClient( process.env.SEARCH_ENDPOINT, "users", new AzureKeyCredential(process.env.SEARCH_API_KEY) ); // 写入用户数据到搜索索引 await searchClient.mergeOrUploadDocuments([ { id: username, username: username, level: 1 } ]); context.res = { status: 200, body: "用户创建成功" }; } catch (error) { context.res = { status: 500, body: `创建出错:${error.message}` }; } }
注意:需要把你的Search服务终结点、API密钥配置到Azure Static Web App的应用程序设置中,对应键名分别为
SEARCH_ENDPOINT和SEARCH_API_KEY,不要把密钥硬编码在代码里。本地调试时在项目的local.settings.json里配置同名参数即可正常运行。
内容的提问来源于stack exchange,提问作者Yoneo12
相关产品推荐
相关产品推荐

