使用 rails 中的活动存储直接上传 - input.dataset.directUploadUrl "undefined"
direct upload using active storage in rails - input.dataset.directUploadUrl "undefined"
使用 rails 6 并尝试将文件 using this drag and drop JS framework 上传到本地磁盘,但我收到“Failed to load resource: the server responded with a status of 404 (Not Found)
”。这是由于未定义 url 变量。
控制台错误:ActionController::RoutingError (No route matches [POST] "/undefined"
。
我已按照此处的所有步骤进行操作:https://edgeguides.rubyonrails.org/active_storage_overview.html。
JS代码:
import { DirectUpload } from "@rails/activestorage"
function uploadFile(file) {
const input = document.querySelector('input[type=file]')
console.log(input)
// your form needs the file_field direct_upload: true, which
// provides data-direct-upload-url
const url = input.dataset.directUploadUrl <-- returns "undefined"
console.log(url)
const upload = new DirectUpload(file, url)
upload.create((error, blob) => {
if (error) {
// Handle the error
} else {
// Add an appropriately-named hidden input to the form with a
// value of blob.signed_id so that the blob ids will be
// transmitted in the normal upload flow
const hiddenField = document.createElement('input')
hiddenField.setAttribute("type", "hidden");
hiddenField.setAttribute("value", blob.signed_id);
hiddenField.name = input.name
document.querySelector('form').appendChild(hiddenField)
}
})
HTML:
<div id="drop-area">
<form class="my-form">
<p>Upload multiple files with the file dialog or by dragging and dropping images onto the dashed region</p>
<input type="file" id="fileElem" multiple accept="image/*" onchange="handleFiles(this.files)" data-direct-upload = "true">
<label class="button" for="fileElem">Select some files</label>
</form>
<progress id="progress-bar" max=100 value=0></progress>
<div id="gallery" /></div>
</div>
<%= javascript_pack_tag 'dropzone.js' %>
我想知道活动存储是否不喜欢没有整齐地打包在嵌入式 ruby 代码中的表单数据,如下所示:
<%= form.file_field :attachments, multiple: true, direct_upload: true %>
方法二:
如果我尝试在不使用活动存储 DirectUpload 方法的情况下发送文件,我会收到“无法加载资源:服务器响应状态为 400(错误请求)”,控制台输出为 ActionController::ParameterMissing (param is missing or the value is empty: blob)
这是 JS 代码:
function uploadFile(file, i) {
var url2 = 'rails/active_storage/direct_uploads'
var xhr = new XMLHttpRequest()
var formData = new FormData()
xhr.open('POST', url2, true)
xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest')
//Update progress (can be used to show progress indicator)
xhr.upload.addEventListener("progress", function(e) {
updateProgress(i, (e.loaded * 100.0 / e.total) || 100)
})
xhr.addEventListener('readystatechange', function(e) {
if (xhr.readyState == 4 && xhr.status == 200) {
updateProgress(i, 100) // <- Add this
}
else if (xhr.readyState == 4 && xhr.status != 200) {
// Error. Inform the user
}
})
formData.append('upload_preset', 'ujpu6gyk')
formData.append('file', file)
xhr.send(formData)
}
在研究了 URL 的使用方法后,'rails/active_storage/direct_uploads'
似乎越过了 404 消息,而是抛出了 400。我无法相信仅仅上传一个文件就这么困难到本地磁盘。请帮忙!
所以我并没有加深对主动存储的理解,但我确实找到了一个有效的解决方案。在方法 1 中,我只是将返回“未定义”的 URL 更改为手动 'rails/active_storage/direct_uploads'
.
JS 代码现在看起来像:
function uploadFile(file) {
// const input = document.querySelector('input[type=file]')
// console.log(input)
// your form needs the file_field direct_upload: true, which
// provides data-direct-upload-url
const url = 'rails/active_storage/direct_uploads' //input.dataset.directUploadUrl
console.log(url)
const upload = new DirectUpload(file, url)
upload.create((error, blob) => {
if (error) {
// Handle the error
} else {
// Add an appropriately-named hidden input to the form with a
// value of blob.signed_id so that the blob ids will be
// transmitted in the normal upload flow
const hiddenField = document.createElement('input')
hiddenField.setAttribute("type", "hidden");
hiddenField.setAttribute("value", blob.signed_id);
hiddenField.name = input.name
document.querySelector('form').appendChild(hiddenField)
}
})
上传后,我可以像这样(从 Ruby 中)对文件进行 blob 操作,而无需将它们下载到临时目录:
blob = ActiveStorage::Blob.first
blob.open do |tempfile|
puts tempfile.path #do some processing
puts blob.filename
end
当你使用 erb 助手时,我刚刚 运行 遇到了类似的问题
<%= form.file_field :images, direct_upload: true %>
生成的输入包含数据直接上传-url,就像这样
<input data-direct-upload-url="http://localhost:3000/rails/active_storage/direct_uploads" type="file" name="post[images]" id="post_images">
在我的例子中,页面上已经有一些其他文件输入,因此来自活动存储示例的默认查询 select
const input = document.querySelector('input[type=file]')
在没有直接上传的情况下返回另一个输入 url,导致出现与您遇到的类似的错误。
使用 rails 6 并尝试将文件 using this drag and drop JS framework 上传到本地磁盘,但我收到“Failed to load resource: the server responded with a status of 404 (Not Found)
”。这是由于未定义 url 变量。
控制台错误:ActionController::RoutingError (No route matches [POST] "/undefined"
。
我已按照此处的所有步骤进行操作:https://edgeguides.rubyonrails.org/active_storage_overview.html。
JS代码:
import { DirectUpload } from "@rails/activestorage"
function uploadFile(file) {
const input = document.querySelector('input[type=file]')
console.log(input)
// your form needs the file_field direct_upload: true, which
// provides data-direct-upload-url
const url = input.dataset.directUploadUrl <-- returns "undefined"
console.log(url)
const upload = new DirectUpload(file, url)
upload.create((error, blob) => {
if (error) {
// Handle the error
} else {
// Add an appropriately-named hidden input to the form with a
// value of blob.signed_id so that the blob ids will be
// transmitted in the normal upload flow
const hiddenField = document.createElement('input')
hiddenField.setAttribute("type", "hidden");
hiddenField.setAttribute("value", blob.signed_id);
hiddenField.name = input.name
document.querySelector('form').appendChild(hiddenField)
}
})
HTML:
<div id="drop-area">
<form class="my-form">
<p>Upload multiple files with the file dialog or by dragging and dropping images onto the dashed region</p>
<input type="file" id="fileElem" multiple accept="image/*" onchange="handleFiles(this.files)" data-direct-upload = "true">
<label class="button" for="fileElem">Select some files</label>
</form>
<progress id="progress-bar" max=100 value=0></progress>
<div id="gallery" /></div>
</div>
<%= javascript_pack_tag 'dropzone.js' %>
我想知道活动存储是否不喜欢没有整齐地打包在嵌入式 ruby 代码中的表单数据,如下所示:
<%= form.file_field :attachments, multiple: true, direct_upload: true %>
方法二:
如果我尝试在不使用活动存储 DirectUpload 方法的情况下发送文件,我会收到“无法加载资源:服务器响应状态为 400(错误请求)”,控制台输出为 ActionController::ParameterMissing (param is missing or the value is empty: blob)
这是 JS 代码:
function uploadFile(file, i) {
var url2 = 'rails/active_storage/direct_uploads'
var xhr = new XMLHttpRequest()
var formData = new FormData()
xhr.open('POST', url2, true)
xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest')
//Update progress (can be used to show progress indicator)
xhr.upload.addEventListener("progress", function(e) {
updateProgress(i, (e.loaded * 100.0 / e.total) || 100)
})
xhr.addEventListener('readystatechange', function(e) {
if (xhr.readyState == 4 && xhr.status == 200) {
updateProgress(i, 100) // <- Add this
}
else if (xhr.readyState == 4 && xhr.status != 200) {
// Error. Inform the user
}
})
formData.append('upload_preset', 'ujpu6gyk')
formData.append('file', file)
xhr.send(formData)
}
在研究了 URL 的使用方法后,'rails/active_storage/direct_uploads'
似乎越过了 404 消息,而是抛出了 400。我无法相信仅仅上传一个文件就这么困难到本地磁盘。请帮忙!
所以我并没有加深对主动存储的理解,但我确实找到了一个有效的解决方案。在方法 1 中,我只是将返回“未定义”的 URL 更改为手动 'rails/active_storage/direct_uploads'
.
JS 代码现在看起来像:
function uploadFile(file) {
// const input = document.querySelector('input[type=file]')
// console.log(input)
// your form needs the file_field direct_upload: true, which
// provides data-direct-upload-url
const url = 'rails/active_storage/direct_uploads' //input.dataset.directUploadUrl
console.log(url)
const upload = new DirectUpload(file, url)
upload.create((error, blob) => {
if (error) {
// Handle the error
} else {
// Add an appropriately-named hidden input to the form with a
// value of blob.signed_id so that the blob ids will be
// transmitted in the normal upload flow
const hiddenField = document.createElement('input')
hiddenField.setAttribute("type", "hidden");
hiddenField.setAttribute("value", blob.signed_id);
hiddenField.name = input.name
document.querySelector('form').appendChild(hiddenField)
}
})
上传后,我可以像这样(从 Ruby 中)对文件进行 blob 操作,而无需将它们下载到临时目录:
blob = ActiveStorage::Blob.first
blob.open do |tempfile|
puts tempfile.path #do some processing
puts blob.filename
end
当你使用 erb 助手时,我刚刚 运行 遇到了类似的问题
<%= form.file_field :images, direct_upload: true %>
生成的输入包含数据直接上传-url,就像这样
<input data-direct-upload-url="http://localhost:3000/rails/active_storage/direct_uploads" type="file" name="post[images]" id="post_images">
在我的例子中,页面上已经有一些其他文件输入,因此来自活动存储示例的默认查询 select
const input = document.querySelector('input[type=file]')
在没有直接上传的情况下返回另一个输入 url,导致出现与您遇到的类似的错误。