Skip to content

GraphQL - JQuery 集成

GraphQL - 基本客户端集成(Fetch/jQuery)

Section titled “GraphQL - 基本客户端集成(Fetch/jQuery)”

尽管像 Apollo Client 这样的专用 GraphQL 客户端库提供了许多优势(缓存、UI 集成),但重要的是要理解,您可以使用标准的 HTTP 请求与任何 GraphQL API 进行交互。这对于简单的客户端、脚本、服务器间通信或在使用没有专用 GraphQL 库的框架(如旧版 jQuery 应用程序)时很有用。

核心原理是向 GraphQL 端点发送 HTTP POST 请求,并将查询放在请求体中。

一个标准的 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 字符串包含多个命名操作,则指定要执行哪个操作。

让我们创建一个简单的 HTML 页面,使用 jQuery 的 $.ajax() 方法与 GraphQL 服务器进行交互。这演示了基本的 HTTP 交互。

确保您有一个正在运行的 GraphQL 服务器。您可以复用之前示例中的服务器(例如,“基本服务器示例”或“React 集成”章节)。对于本例,我们假设服务器运行在 http://localhost:9000/graphql,并支持以下模式(Schema):

# 服务器模式(Schema)(示例)
type Query {
greeting: String
sayHello(name: String!): String
}

步骤 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>
  • 引入 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。
  1. 确保您的 GraphQL 服务器正在运行(在服务器项目文件夹中运行 npm start 或 npm run dev)。

  2. 直接在您的网页浏览器中打开 jquery-client.html 文件(文件 > 打开文件,或双击)。

  3. 点击“Fetch Greeting”(获取问候语)和“Say Hello”(打招呼)按钮。您应该能在页面上看到从 GraphQL 服务器获取的结果。检查浏览器的开发者控制台(F12)查看详细日志。

您可以使用浏览器原生 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 数据。虽然客户端库自动化了这一过程,但理解其底层机制是很有价值的。