Rails通过javascript的fetch方法请求post或put等非get的api的时候问题
如果你用Fetch API发送非get请求给一个Rails的controller,你可能会bump into 那个 InvalidAuthenticityToken异常。
那是因为Rails需要一个特别的 CSRF token去验证这个request,你可以通过 X-CSRF-Token头传过去。
这里有个一个例子:
那是因为Rails需要一个特别的 CSRF token去验证这个request,你可以通过 X-CSRF-Token头传过去。
这里有个一个例子:
// Grab the CSRF token from the meta tag const csrfToken = document.querySelector("[name='csrf-token']").content fetch("/v1/articles", { method: "POST", headers: { "X-CSRF-Token": csrfToken, // 👈👈👈 Set the token "Content-Type": "application/json" }, body: JSON.stringify({ title: "awesome post" }) }).then(response => { if (!response.ok) { throw response; } return response.json() }).then((data) => { console.log(data) }).catch(error => { console.error("error", error) })
在old-fashioned Rails apps, CSRF token是通过rails-ujs 来传输的 transparently, 所以你不需要做额外的工作。
无论如何,如果你正咋运行 Rails + React 或者 vanilla JavaScript 香草味道的JavaScript,也就是原味原生的javascript,你想在前端去fire这个原始的requests, 你将会需要上面的方式将代码 the code snippet ,在html的markup里面去grab 抓去这个CSRF token,并把它放到headers里面传过去。
测试环境下, 页面不会生成这个csrf-token的meta tag,所以你可能就抓不到这个。
你可以将这个代码放到 utils.js里面
export function getCSRFToken() { const csrfToken = document.querySelector("[name='csrf-token']") if (csrfToken) { return csrfToken.content } else { return null } }
在rails+stimulus.js里具体的用法就是:
#javascript/controllers/utils.js
export default function getCSRFToken() { const csrfToken = document.querySelector("[name='csrf-token']") if (csrfToken) { return csrfToken.content } else { return null } }
不要忘记调用个getCSRFToken() 带上圆括号哦。
#./javascript/controllers/post_controller.js
import { Controller } from "@hotwired/stimulus" import getCSRFToken from "controllers/utils" //import getCSRFToken from "./utils" # 这里不能用./utils,因为在生产环境下这种表达方式,会提示找不到utils文件。 ... ... fetch(this.turlValue, { method: "PUT",// non-GET headers: {"X-CSRF-Token": getCSRFToken() } }) .then(response+> response.text()) ... ...
阅读量: 714
发布于:
修改于:
发布于:
修改于: