GraphQL - JQuery 集成
GraphQL - 基本客户端集成(Fetch/jQuery)
Section titled “GraphQL - 基本客户端集成(Fetch/jQuery)”尽管像 Apollo Client 这样的专用 GraphQL 客户端库提供了许多优势(缓存、UI 集成),但重要的是要理解,您可以使用标准的 HTTP 请求与任何 GraphQL API 进行交互。这对于简单的客户端、脚本、服务器间通信或在使用没有专用 GraphQL 库的框架(如旧版 jQuery 应用程序)时很有用。
核心原理是向 GraphQL 端点发送 HTTP POST 请求,并将查询放在请求体中。
GraphQL HTTP 请求结构
Section titled “GraphQL HTTP 请求结构”一个标准的 GraphQL HTTP 请求通常包括:
- URL:GraphQL 服务器提供的单一端点(例如,
http://yourserver.com/graphql)。 - 方法:
POST(虽然GET有时可用于查询,但POST是查询的标准方法,并且变更(Mutation)必须使用POST)。 - 请求头(Headers):
- 请求体(Body):一个 JSON 对象,包含:
{ "query": "... your GraphQL query string ...", "variables": { ... optional variables object ... }, "operationName": "... optional operation name ..."}query:(必需)GraphQL 查询或变更(Mutation)字符串。variables:(可选)一个对象,包含查询字符串中定义的变量的值。operationName:(可选)如果query字符串包含多个命名操作,则指定要执行哪个操作。
示例:jQuery 客户端
Section titled “示例:jQuery 客户端”让我们创建一个简单的 HTML 页面,使用 jQuery 的 $.ajax() 方法与 GraphQL 服务器进行交互。这演示了基本的 HTTP 交互。
设置服务器(复用或创建)
Section titled “设置服务器(复用或创建)”确保您有一个正在运行的 GraphQL 服务器。您可以复用之前示例中的服务器(例如,“基本服务器示例”或“React 集成”章节)。对于本例,我们假设服务器运行在 http://localhost:9000/graphql,并支持以下模式(Schema):
# 服务器模式(Schema)(示例)type Query { greeting: String sayHello(name: String!): String}设置客户端(HTML 和 jQuery)
Section titled “设置客户端(HTML 和 jQuery)”步骤 1:创建 HTML 文件(index.html)
Section titled “步骤 1:创建 HTML 文件(index.html)”创建一个 HTML 文件(例如 jquery-client.html),放在新文件夹中或浏览器可访问的任何位置。
<!DOCTYPE html><html><head> <title>jQuery GraphQL Client</title> <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script> <style> body { font-family: sans-serif; } section { margin-bottom: 20px; padding: 15px; border: 1px solid #ccc; } #greetingResult, #sayHelloResult { margin-top: 10px; font-weight: bold; min-height: 20px; } .error { color: red; } .loading { color: blue; } </style></head><body>
<h1>Simple jQuery GraphQL Client</h1>
<section> <h2>Get Greeting</h2> <button id="btnGreet">Fetch Greeting</button> <div id="greetingResult"></div> </section>
<hr/>
<section> <h2>Say Hello</h2> <label for="txtName">Enter Name:</label> <input type="text" id="txtName" value="jQuery User"/> <button id="btnSayHello">Say Hello</button> <div id="sayHelloResult"></div> </section>
<script> $(document).ready(function() { const GRAPHQL_ENDPOINT = 'http://localhost:9000/graphql';
// --- 用于发送 GraphQL 请求的辅助函数 --- function makeGraphQLRequest(query, variables, resultElementId) { const resultDiv = $('#' + resultElementId); resultDiv.html('Loading...').removeClass('error').addClass('loading');
$.ajax({ url: GRAPHQL_ENDPOINT, method: 'POST', contentType: 'application/json', headers: { 'Accept': 'application/json' // 如果需要,在此处添加 Authorization 头: // 'Authorization': 'Bearer YOUR_TOKEN' }, data: JSON.stringify({ query: query, variables: variables || null // 如果没有变量则发送 null }), success: function(response) { resultDiv.removeClass('loading'); if (response.errors) { console.error('GraphQL Errors:', response.errors); resultDiv.html('Error: ' + response.errors[0].message).addClass('error'); } else if (response.data) { console.log('GraphQL Data:', response.data); // 显示数据(根据您的查询结构进行调整) if (resultElementId === 'greetingResult' && response.data.greeting) { resultDiv.html('Server says: ' + response.data.greeting); } else if (resultElementId === 'sayHelloResult' && response.data.sayHello) { resultDiv.html('Server says: ' + response.data.sayHello); } else { resultDiv.html(JSON.stringify(response.data)); // 后备显示 } } else { resultDiv.html('Unexpected response format.').addClass('error'); } }, error: function(jqXHR, textStatus, errorThrown) { console.error('AJAX Error:', textStatus, errorThrown, jqXHR.responseText); resultDiv.removeClass('loading'); resultDiv.html('AJAX Error: ' + textStatus).addClass('error'); } }); }
// --- 按钮点击处理函数 ---
// 问候按钮 $('#btnGreet').click(function() { const greetingQuery = ` query GetGreeting { greeting } `; makeGraphQLRequest(greetingQuery, null, 'greetingResult'); });
// 打招呼按钮 $('#btnSayHello').click(function() { const name = $('#txtName').val(); if (!name) { $('#sayHelloResult').html('Please enter a name.').addClass('error'); return; }
const sayHelloQuery = ` query SayHello($name: String!) { sayHello(name: $name) } `; const variables = { name: name }; makeGraphQLRequest(sayHelloQuery, variables, 'sayHelloResult'); });
}); </script>
</body></html>步骤 2:理解代码
Section titled “步骤 2:理解代码”- 引入 jQuery:我们从 CDN 链接到 jQuery 库。
- HTML 结构:基本的按钮和 div 用于触发请求和显示结果。
GRAPHQL_ENDPOINT:存储您服务器的 URL。makeGraphQLRequest函数:- 接收
query字符串、可选的variables对象以及用于显示结果的 HTML 元素的 ID。 - 设置加载状态。
- 使用配置为
POST请求的$.ajax()。 - 将
contentType和Accept请求头设置为application/json。 - 关键在于,将
data选项设置为一个字符串化的 JSON 对象,其中包含query和variables。 - 处理
success和error回调函数。 - 在
success中,它检查response.errors(GraphQL 错误)和response.data(成功结果)。 - 使用结果或错误消息更新目标 div。
- 按钮处理函数:
- 定义 GraphQL 查询字符串(使用模板字面量(template literals)提高可读性)。
- 对于
sayHello,创建一个与查询变量($name)匹配的variables对象。 - 使用适当的查询、变量和结果 div ID 调用
makeGraphQLRequest。
步骤 3:运行客户端
Section titled “步骤 3:运行客户端”-
确保您的 GraphQL 服务器正在运行(在服务器项目文件夹中运行
npm start或npm run dev)。 -
直接在您的网页浏览器中打开
jquery-client.html文件(文件 > 打开文件,或双击)。 -
点击“Fetch Greeting”(获取问候语)和“Say Hello”(打招呼)按钮。您应该能在页面上看到从 GraphQL 服务器获取的结果。检查浏览器的开发者控制台(F12)查看详细日志。
使用原生 fetch API
Section titled “使用原生 fetch API”您可以使用浏览器原生 fetch API(在现代浏览器中是标准)来实现同样的结果,而无需 jQuery:
async function fetchGraphQL(query, variables) { const GRAPHQL_ENDPOINT = 'http://localhost:9000/graphql';
try { const response = await fetch(GRAPHQL_ENDPOINT, { method: 'POST', headers: { 'Content-Type': 'application/json', 'Accept': 'application/json', // 如果需要,在此处添加 Authorization 头: // 'Authorization': 'Bearer YOUR_TOKEN' }, body: JSON.stringify({ query: query, variables: variables || null }) });
if (!response.ok) { // 处理 HTTP 错误(例如 4xx, 5xx) throw new Error(`HTTP error! status: ${response.status}`); }
const data = await response.json(); // 解析 JSON 响应 return data; // 包含 { data: ... } 或 { errors: [...] }
} catch (error) { console.error("Error fetching GraphQL:", error); // 返回一个指示错误的对象以便一致处理 return { errors: [{ message: error.message || 'Network request failed' }] }; }}
// 示例用法:document.getElementById('btnGreet').addEventListener('click', async () => { const resultDiv = document.getElementById('greetingResult'); resultDiv.textContent = 'Loading...'; resultDiv.classList.remove('error'); resultDiv.classList.add('loading');
const greetingQuery = '{ greeting }'; const response = await fetchGraphQL(greetingQuery);
resultDiv.classList.remove('loading'); if (response.errors) { resultDiv.textContent = 'Error: ' + response.errors[0].message; resultDiv.classList.add('error'); } else if (response.data) { resultDiv.textContent = 'Server says: ' + response.data.greeting; }});
// 为 sayHello 按钮添加类似的监听器...这个 fetch 示例镜像了 $.ajax 的逻辑,但使用了现代的 async/await 语法和标准浏览器 API。
通过 HTTP 与 GraphQL 交互归根结底就是发送一个 POST 请求,其包含您的查询和变量的特定 JSON 数据。虽然客户端库自动化了这一过程,但理解其底层机制是很有价值的。