有没有办法在 fetch 调用后呈现 js.erb ?
Is there a way to render a js.erb after a fetch call?
在我的 Rails 应用程序中,我想在 fetch 调用后呈现一个 js.erb 部分,但由于某些我不明白的原因,它不起作用。如果你能帮助我,那就太好了。
在一个视图中,一个事件触发了这个基本上执行获取请求的函数:
function updateState(id, state){
const csrfToken = document.querySelector('meta[name="csrf-token"]').attributes
.content.value;
fetch(window.location.origin + "/update_state", {
method: "POST",
headers: {
'Accept': "JS",
"Content-Type": "application/json",
"X-CSRF-Token": csrfToken
},
body: JSON.stringify({'id': id, 'state': state}),
credentials: "same-origin"
})
}
然后在我的控制器中:
def update_state
@model = Model.find(params[:id])
authorize @model
@model.update(state: params[:state])
respond_to do |format|
format.html { redirect_to xxx }
format.js
end
end
在我的 js.erb 文件中:
console.log('hello');
但是,在这种情况下,我从服务器收到错误消息:
ActionController::UnknownFormat
在行 'respond_to 做 |format|
我感觉服务器不理解获取的 header:
'Accept': "JS"
当我查看服务器的日志时:
Started POST "/update_state" for 127.0.0.1 at 2019-04-04 11:22:49 +0200
Processing by ModelsController#update_state as JS
但是我觉得Rails不认识。我该怎么办?
我也在控制器中尝试过这个:
def update_state
@model = Model.find(params[:id])
authorize @model
@model.update(state: params[:state])
render 'update_state.js', layout: false
end
这不会触发错误。我在客户端收到了 js.erb。但是,它没有执行(console.log不执行)。
你有什么想法吗?非常感谢您的帮助。
编辑:查看编辑以获取有关手动触发 .js.erb 文件的完整解决方案。
有同样的问题,这里实际上有两个问题。你是对的,你的 headers 不是。这些 headers 触发 .js.erb
对我有用并且看起来很正确:
'dataType': 'json',
'contentType': 'application/json; charset=utf-8',
'X-Requested-With': 'XMLHttpRequest',
'X-CSRF-Token': - your CSRF method to get the token -
但其次要触发 js 响应,您的 respond_to
块 :
respond_to do |format|
format.html { redirect_to xxx }
format.js
end
必须先有 format.js。由于 rails 对 HTML 有响应,它将首先响应 HTML 并且似乎甚至不寻找下一个格式块。
respond_to do |format|
format.js
format.html { redirect_to xxx }
end
希望对您有所帮助:-)
编辑 2018 年 11 月 13 日
大家好,好久不见!同样的问题又发生在我身上,我之前的回复并没有解决问题。与您一样,呈现了 .js.erb 文件但没有任何反应,并且未显示 console.log
。所以我创建了一个 link_to
和 remote: true
触发了我的 .js.erb
文件并比较了请求。一切都一样,除了一件事:请求的类型。一个是抓取,另一个是 xhr
。 .js.erb
文件似乎仅由 xhr
请求触发。所以解决方案是构建一个旧的 xhr
请求而不是获取,如下所示:
const url = 'your_custom_path' // Build the url to fetch
const csrf = document.querySelector('meta[name="csrf-token"]').getAttribute('content')
let xhr = new XMLHttpRequest();
// Will be a GET request here
xhr.open('GET', url, false);
// Setting the headers
xhr.setRequestHeader('Content-Type', 'application/json');
xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
xhr.setRequestHeader('X-CSRF-Token', csrf);
xhr.setRequestHeader('dataType', 'script');
// What to do with the response
xhr.onload = function() {
let responseObj = xhr.response
eval(responseObj) // You need to eval() manually the response for it to be executed
}
// Sending the request
xhr.send()
希望对您有所帮助,即使是在几个月后! ;)
我反过来管理。我从未成功 js.erb.
因此,我使用带有文本响应的提取调用:
function updateState(id, state){
const csrfToken = document.querySelector('meta[name="csrf-token"]').attributes
.content.value;
fetch(window.location.origin + "/update_state", {
method: "POST",
headers: {
'Accept': "JS",
"Content-Type": "application/json",
"X-CSRF-Token": csrfToken
},
body: JSON.stringify({'id': id, 'state': state}),
credentials: "same-origin"
}).then(response => response.text())
.then(data => {
div.inserAdjacentHTML('XXX', data);
});
}
然后在 controller/action:
def update_state
@model = Model.find(params[:id])
authorize @model
@model.update(state: params[:state])
render 'update_state.js', layout: false, content_type: "text/plain"
end
这样就可以了。希望对你有帮助。
我 运行 在 Rails 6 中使用 fetch 解决了这个问题。只需将 format.js 置于 format.html 上方即可解决我的问题。谢谢@holino。以下提取有效。
fetch(event.currentTarget.dataset.destroyPath, {
method: 'DELETE',
dataType: 'script',
credentials: 'include',
headers: {
'X-CSRF-Token': csrf
},
})
在我的 Rails 应用程序中,我想在 fetch 调用后呈现一个 js.erb 部分,但由于某些我不明白的原因,它不起作用。如果你能帮助我,那就太好了。
在一个视图中,一个事件触发了这个基本上执行获取请求的函数:
function updateState(id, state){
const csrfToken = document.querySelector('meta[name="csrf-token"]').attributes
.content.value;
fetch(window.location.origin + "/update_state", {
method: "POST",
headers: {
'Accept': "JS",
"Content-Type": "application/json",
"X-CSRF-Token": csrfToken
},
body: JSON.stringify({'id': id, 'state': state}),
credentials: "same-origin"
})
}
然后在我的控制器中:
def update_state
@model = Model.find(params[:id])
authorize @model
@model.update(state: params[:state])
respond_to do |format|
format.html { redirect_to xxx }
format.js
end
end
在我的 js.erb 文件中:
console.log('hello');
但是,在这种情况下,我从服务器收到错误消息: ActionController::UnknownFormat 在行 'respond_to 做 |format| 我感觉服务器不理解获取的 header: 'Accept': "JS"
当我查看服务器的日志时:
Started POST "/update_state" for 127.0.0.1 at 2019-04-04 11:22:49 +0200
Processing by ModelsController#update_state as JS
但是我觉得Rails不认识。我该怎么办?
我也在控制器中尝试过这个:
def update_state
@model = Model.find(params[:id])
authorize @model
@model.update(state: params[:state])
render 'update_state.js', layout: false
end
这不会触发错误。我在客户端收到了 js.erb。但是,它没有执行(console.log不执行)。
你有什么想法吗?非常感谢您的帮助。
编辑:查看编辑以获取有关手动触发 .js.erb 文件的完整解决方案。
有同样的问题,这里实际上有两个问题。你是对的,你的 headers 不是。这些 headers 触发 .js.erb
对我有用并且看起来很正确:
'dataType': 'json',
'contentType': 'application/json; charset=utf-8',
'X-Requested-With': 'XMLHttpRequest',
'X-CSRF-Token': - your CSRF method to get the token -
但其次要触发 js 响应,您的 respond_to
块 :
respond_to do |format|
format.html { redirect_to xxx }
format.js
end
必须先有 format.js。由于 rails 对 HTML 有响应,它将首先响应 HTML 并且似乎甚至不寻找下一个格式块。
respond_to do |format|
format.js
format.html { redirect_to xxx }
end
希望对您有所帮助:-)
编辑 2018 年 11 月 13 日
大家好,好久不见!同样的问题又发生在我身上,我之前的回复并没有解决问题。与您一样,呈现了 .js.erb 文件但没有任何反应,并且未显示 console.log
。所以我创建了一个 link_to
和 remote: true
触发了我的 .js.erb
文件并比较了请求。一切都一样,除了一件事:请求的类型。一个是抓取,另一个是 xhr
。 .js.erb
文件似乎仅由 xhr
请求触发。所以解决方案是构建一个旧的 xhr
请求而不是获取,如下所示:
const url = 'your_custom_path' // Build the url to fetch
const csrf = document.querySelector('meta[name="csrf-token"]').getAttribute('content')
let xhr = new XMLHttpRequest();
// Will be a GET request here
xhr.open('GET', url, false);
// Setting the headers
xhr.setRequestHeader('Content-Type', 'application/json');
xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
xhr.setRequestHeader('X-CSRF-Token', csrf);
xhr.setRequestHeader('dataType', 'script');
// What to do with the response
xhr.onload = function() {
let responseObj = xhr.response
eval(responseObj) // You need to eval() manually the response for it to be executed
}
// Sending the request
xhr.send()
希望对您有所帮助,即使是在几个月后! ;)
我反过来管理。我从未成功 js.erb.
因此,我使用带有文本响应的提取调用:
function updateState(id, state){
const csrfToken = document.querySelector('meta[name="csrf-token"]').attributes
.content.value;
fetch(window.location.origin + "/update_state", {
method: "POST",
headers: {
'Accept': "JS",
"Content-Type": "application/json",
"X-CSRF-Token": csrfToken
},
body: JSON.stringify({'id': id, 'state': state}),
credentials: "same-origin"
}).then(response => response.text())
.then(data => {
div.inserAdjacentHTML('XXX', data);
});
}
然后在 controller/action:
def update_state
@model = Model.find(params[:id])
authorize @model
@model.update(state: params[:state])
render 'update_state.js', layout: false, content_type: "text/plain"
end
这样就可以了。希望对你有帮助。
我 运行 在 Rails 6 中使用 fetch 解决了这个问题。只需将 format.js 置于 format.html 上方即可解决我的问题。谢谢@holino。以下提取有效。
fetch(event.currentTarget.dataset.destroyPath, {
method: 'DELETE',
dataType: 'script',
credentials: 'include',
headers: {
'X-CSRF-Token': csrf
},
})