EP092. “REST API 删除请求与 Nonce 身份验证”
🔒 登录后可标记已读接上一讲,把删除按钮真正接上 WordPress REST API。因为 note 文章类型注册时已经开了 show_in_rest,所以自动拥有标准 REST 端点,直接对 wp-json/wp/v2/note/{ID} 发送 DELETE 类型的请求即可删除。这里第一次用到 $.ajax() 而不是 $.getJSON()(后者只能发 GET)。第一次尝试会被 WordPress 拒绝(401 Unauthorized),因为请求没有带上身份凭证——WordPress REST API 默认不信任任何未经验证的写操作。解法是用 Nonce(一次性验证码)证明请求确实来自当前登录用户,通过 wp_localize_script() 把服务端生成的 nonce 悄悄塞进页面数据里,前端发请求时带上它。
涉及文件
wp-content/themes/fictional-university-theme/src/modules/MyNotes.js(修改)wp-content/themes/fictional-university-theme/functions.php(修改)
代码实现
functions.php:给 wp_localize_script 补上 nonce 属性(在已有的 root_url 旁边追加):
// wp-content/themes/fictional-university-theme/functions.php
wp_localize_script('main-university-js', 'universityData', array(
'root_url' => get_site_url(),
'nonce' => wp_create_nonce('wp_rest') // 新增
));
src/modules/MyNotes.js:deleteNote() 改用 $.ajax() 发送带身份验证的 DELETE 请求(ID 暂时写死,下一讲改成动态):
// wp-content/themes/fictional-university-theme/src/modules/MyNotes.js
deleteNote() {
$.ajax({
beforeSend: xhr => {
xhr.setRequestHeader("X-WP-Nonce", universityData.nonce)
},
url: universityData.root_url + "/wp-json/wp/v2/note/58", // 58 是本地测试环境里某条笔记的 ID,实际数字因人而异
type: "DELETE",
success: response => {
console.log("Congrats")
console.log(response)
},
error: response => {
console.log("Sorry")
console.log(response)
}
})
}
关键改动点:
$.getJSON()只能发 GET 请求,删除/新建/更新这些写操作要改用更底层的$.ajax(),可以在type属性里显式指定'DELETE'/'POST'等- WordPress REST API 的写操作(POST/PUT/DELETE)默认要求身份验证,直接发请求会收到 401 Unauthorized、提示「你没有权限删除这篇文章」——这是刻意的安全设计,不是 bug,如果匿名请求能随便删内容,那才是真正的安全漏洞
wp_create_nonce('wp_rest')在服务端为当前登录用户生成一个绑定到'wp_rest'这个 action 名的一次性验证码,通过已有的wp_localize_script()一并注入到前端可以访问的universityData对象里(这个函数在项目里第一次使用是为了传root_url,这次只是多加一个属性,机制完全一样)- 前端在
$.ajax()的beforeSend回调里,用浏览器原生的xhr.setRequestHeader()把这个 nonce 塞进请求头,请求头的名字必须精确匹配X-WP-Nonce——这是 WordPress REST API 专门检查的固定头名,改成别的名字不会被识别 success/error回调都用 ES6 箭头函数,并在参数里接收response,方便在控制台打印调试信息,确认请求到底成功还是失败、失败原因是什么
[截图:浏览器开发者工具 Network 面板,DELETE 请求到 wp-json/wp/v2/note/58 的请求头(含 X-WP-Nonce)与响应结果]
Hook / Function 速查
| 名称 | 类型 | 用途 |
|---|---|---|
$.ajax(options) | jQuery 方法 | 发送可自定义请求类型(GET/POST/DELETE 等)的请求,比 $.getJSON() 更灵活 |
wp_create_nonce($action) | WP 内建 function | 为当前用户生成一个绑定到指定 action 名的一次性验证码 |
xhr.setRequestHeader(name, value) | 浏览器原生 API | 在发送请求前手动添加自定义请求头 |
X-WP-Nonce | WP REST API 约定的请求头 | WordPress REST API 专门识别这个请求头来验证请求是否来自已登录用户 |
常见坑
- 用
$.getJSON()尝试发 DELETE 请求——这个方法只能发 GET,写操作必须换用$.ajax()并显式指定type - 发请求不带 nonce,直接被 401 拒绝——这是 WordPress 故意的安全机制,不是配置错误,必须补上
X-WP-Nonce请求头才能通过身份验证 beforeSend后面忘记加逗号——转录里作者自己也提到这个笔误,$.ajax()参数对象里每个属性之间都要用逗号隔开,少一个逗号整个对象就会解析出错
延伸 / 后续讲座会用到
现在删除请求已经能成功执行,但① ID 还是写死的 58,需要改成动态获取当前点击的是哪条笔记;② 删除成功后页面没有任何视觉反馈,需要手动刷新才能看到笔记消失——这两点都会在下一讲解决。
Sources
Udemy:
- Become a WordPress Developer: Unlocking Power With Code — Section 19, EP092