React+Pinecone+OpenAI向Pinecone Upsert嵌入向量时遇CORS错误
React集成Pinecone存储OpenAI嵌入向量时的CORS错误解决
问题场景
在React客户端(标注"use-client")中使用LangChain与Pinecone向量数据库存储OpenAI生成的文本嵌入向量,代码执行到console.log(docs)均正常,但调用PineconeStore.fromDocuments时触发CORS错误,具体表现为:请求Pinecone的upsert接口时,返回No 'Access-Control-Allow-Origin' header present on the requested resource。
出错代码示例
"use-client" import { loadQAStuffChain } from "langchain/chains"; import { OpenAI } from "langchain/llms/openai"; import { Document } from "langchain/document"; import { OpenAIEmbeddings } from "langchain/embeddings/openai"; import { PineconeStore } from "langchain/vectorstores/pinecone"; import { PineconeClient } from "@pinecone-database/pinecone"; import React from "react"; export const pine = async () => { const embeddings = new OpenAIEmbeddings({ openAIApiKey: "******" }); const model = new OpenAI({ openAIApiKey: "*******"}); const chain = loadQAStuffChain(model); const docs = [ new Document({ pageContent: "India is located in Asia." }), new Document({ pageContent: "India is surrounded by 3 seas and a mountain range." }), ]; const pinecone = new PineconeClient(); await pinecone.init({ environment: "*****", apiKey: "******", }); pinecone.projectName="1a65f5a" const index = pinecone.Index("pine"); console.log(docs) const store = await PineconeStore.fromDocuments(docs, embeddings,{ pineconeIndex: index, namespace: "pine1234" }) };
核心原因
Pinecone的官方API不支持浏览器端直接跨域请求,同时直接在客户端暴露Pinecone API密钥和OpenAI密钥存在严重的安全风险,这是平台刻意限制的行为。
解决方案
1. 将向量存储逻辑迁移到后端(推荐生产环境)
把与Pinecone、OpenAI交互的代码移到服务器端(比如Next.js API路由、Express服务器),前端仅通过接口传递需要处理的文本数据。
示例后端代码(Next.js 13+ API路由)
// app/api/vector-store/route.ts import { loadQAStuffChain } from "langchain/chains"; import { OpenAI } from "langchain/llms/openai"; import { Document } from "langchain/document"; import { OpenAIEmbeddings } from "langchain/embeddings/openai"; import { PineconeStore } from "langchain/vectorstores/pinecone"; import { PineconeClient } from "@pinecone-database/pinecone"; import { NextResponse } from "next/server"; export async function POST(request: Request) { try { const { docs } = await request.json(); // 从环境变量读取密钥,禁止硬编码 const embeddings = new OpenAIEmbeddings({ openAIApiKey: process.env.OPENAI_API_KEY! }); const model = new OpenAI({ openAIApiKey: process.env.OPENAI_API_KEY! }); const chain = loadQAStuffChain(model); const pinecone = new PineconeClient(); await pinecone.init({ environment: process.env.PINECONE_ENVIRONMENT!, apiKey: process.env.PINECONE_API_KEY!, }); pinecone.projectName = "1a65f5a"; const index = pinecone.Index("pine"); const store = await PineconeStore.fromDocuments( docs.map(doc => new Document(doc)), embeddings, { pineconeIndex: index, namespace: "pine1234" } ); return NextResponse.json({ success: true, message: "向量存储成功" }); } catch (error) { return NextResponse.json({ success: false, error: (error as Error).message }, { status: 500 }); } }
前端修改后的调用代码
"use-client" import React from "react"; export const pine = async () => { const docs = [ { pageContent: "India is located in Asia." }, { pageContent: "India is surrounded by 3 seas and a mountain range." }, ]; try { const response = await fetch("/api/vector-store", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ docs }) }); const result = await response.json(); console.log(result); } catch (error) { console.error("存储失败:", error); } };
2. 本地临时调试(仅用于开发,禁止生产)
如果只是本地开发测试,可以使用CORS代理工具绕过限制,但绝对不能在生产环境使用,因为会暴露敏感密钥。比如使用cors-anywhere:
npx cors-anywhere --port 8080
随后需修改PineconeClient的请求配置,将请求转发至代理地址(具体配置需结合PineconeClient版本调整)。
内容的提问来源于stack exchange,提问作者Animo
相关产品推荐
相关产品推荐

