在 Phoenix 框架中使用 jquery ajax post 提交 POST 请求
Using jquery ajax post to submit a POST request in Phoenix Framework
我们想使用我们的内容可编辑,利用在 router.ex 中生成的路由:
pipeline :browser do
plug :accepts, ["html"]
plug :fetch_session
plug :fetch_flash
plug :put_secure_browser_headers
end
pipeline :api do
plug :accepts, ["json"]
end
scope "/", TextEditor do
pipe_through :browser # Use the default browser stack
get "/", PageController, :index
resources "/posts", PostController
end
和控制器功能,即创建:
def create(conn, %{"post" => post_params}) do
changeset = Post.changeset(%Post{}, post_params)
case Repo.insert(changeset) do
{:ok, _post} ->
conn
|> put_flash(:info, "Post created successfully.")
|> redirect(to: post_path(conn, :index))
{:error, changeset} ->
render(conn, "new.html", changeset: changeset)
end
end
但是我们不想使用生成的表单,然后我们尝试使用 div 和 jquery 方法 $.post:
来测试它
<div id="newPost" contenteditable="true">write here</div>
<div id="button" class="btn btn-primary">Save</div>
<script type="text/javascript">
$(document).ready(function(){
$("#button").click(function() {
var post = $("#newPost").html();
$.post( "/posts/post", { title: post })
.done(function() {
alert( "Data Loaded: " );
});
});
});
</script>
但是我们没有收到警报或任何数据插入我们的数据库。
我们缺少什么?
编辑:在浏览器管道中,由于 csrf 令牌错误,我们删除了交叉伪造插件。
尝试以下操作:
$.post( "/posts", { post: { title: post } })
您的控制器希望参数嵌套在 post
的键下
def create(conn, %{"post" => post_params}) do
我不建议这样做,但您可以将控制器更改为:
def create(conn, %{} = post_params) do
查找没有根 post
键的参数。但是,使用 post
键意味着您可以轻松获得与表单无关的其他参数。
我也不建议禁用 CSRF 检查。您可以通过将 CSRF 令牌存储在元标记中来轻松提交:
<meta name="csrf" content="<%= Plug.CSRFProtection.get_csrf_token() %>">
然后将其作为 header 添加到您的 post 请求中:
var csrf = document.querySelector("meta[name=csrf]").content;
$.ajax({
url: "/posts",
type: "post",
data: {
post: { title: post } })
},
headers: {
"X-CSRF-TOKEN": csrf
},
dataType: "json",
success: function (data) {
console.log(data);
}
});
我们想使用我们的内容可编辑,利用在 router.ex 中生成的路由:
pipeline :browser do
plug :accepts, ["html"]
plug :fetch_session
plug :fetch_flash
plug :put_secure_browser_headers
end
pipeline :api do
plug :accepts, ["json"]
end
scope "/", TextEditor do
pipe_through :browser # Use the default browser stack
get "/", PageController, :index
resources "/posts", PostController
end
和控制器功能,即创建:
def create(conn, %{"post" => post_params}) do
changeset = Post.changeset(%Post{}, post_params)
case Repo.insert(changeset) do
{:ok, _post} ->
conn
|> put_flash(:info, "Post created successfully.")
|> redirect(to: post_path(conn, :index))
{:error, changeset} ->
render(conn, "new.html", changeset: changeset)
end
end
但是我们不想使用生成的表单,然后我们尝试使用 div 和 jquery 方法 $.post:
来测试它<div id="newPost" contenteditable="true">write here</div>
<div id="button" class="btn btn-primary">Save</div>
<script type="text/javascript">
$(document).ready(function(){
$("#button").click(function() {
var post = $("#newPost").html();
$.post( "/posts/post", { title: post })
.done(function() {
alert( "Data Loaded: " );
});
});
});
</script>
但是我们没有收到警报或任何数据插入我们的数据库。 我们缺少什么?
编辑:在浏览器管道中,由于 csrf 令牌错误,我们删除了交叉伪造插件。
尝试以下操作:
$.post( "/posts", { post: { title: post } })
您的控制器希望参数嵌套在 post
def create(conn, %{"post" => post_params}) do
我不建议这样做,但您可以将控制器更改为:
def create(conn, %{} = post_params) do
查找没有根 post
键的参数。但是,使用 post
键意味着您可以轻松获得与表单无关的其他参数。
我也不建议禁用 CSRF 检查。您可以通过将 CSRF 令牌存储在元标记中来轻松提交:
<meta name="csrf" content="<%= Plug.CSRFProtection.get_csrf_token() %>">
然后将其作为 header 添加到您的 post 请求中:
var csrf = document.querySelector("meta[name=csrf]").content;
$.ajax({
url: "/posts",
type: "post",
data: {
post: { title: post } })
},
headers: {
"X-CSRF-TOKEN": csrf
},
dataType: "json",
success: function (data) {
console.log(data);
}
});