1

私は Ruby + Sinatra を学んでいて、ファイルのアップロード方法について説明している良い記事を見つけました。

post '/upload/:filename' do
  userdir = "./upload"
  FileUtils.mkdir_p(userdir) unless File.exists?(userdir)
  filename = File.join(userdir, params[:filename])
  datafile = params[:data]
  File.open(filename, 'wb') do |file|
    file.write(datafile[:tempfile].read)
  end
end

次の cURL コマンドを使用して、ファイルを正常にアップロードできます。

curl -v -F "data=@/Users/me/Desktop/test.pdf"  http://localhost:4567/upload/test.pdf

しかし今は、JSON を使用してすべての着信/発信応答を処理することにしました。これを試してみましたが、うまくいかないようでした。

curl -i -X POST -H Accept:application/json -H Content-Type:application/json -d '{file:{filename:"test.pdf",md5sum:"ab3d2f"}}'  --data-binary @/Users/me/Desktop/test.pdf 'http://localhost:4567/upload/test.pdf'

次のようなエラーも受け取りました。

NoMethodError at /upload/test.pdf
undefined method `get' for #<WebTest:0x101374dd8>
file: web.rb location: POST /upload/:filename line: 48

私は今どうすればいい?

編集:

48号線はこちらfile.write(datafile[:tempfile].read

助けてください!

4

3 に答える 3

2

2番目のcurlコマンドに何が期待されているかはわかりませんが、期待どおりに機能していないことは確かです。--dataカールするパラメータを複数-d指定すると、それらの値は。で区切られて結合され&ます。

たとえば、test.txtコンテンツThis is a test.を含むファイルがあり、次のようにリクエストした場合:

curl -i -X POST -H Accept:application/json -H Content-Type:application/json \
    -d '{file:{filename:"test.txt",md5sum:"ab3d2f"}}'                  \
    --data-binary @test.txt 'http://localhost:4567/upload/test.txt'

リクエストは次のようになります。

POST /upload/test.txt HTTP/1.1
User-Agent: curl/7.24.0 (x86_64-apple-darwin12.0) libcurl/7.24.0 OpenSSL/0.9.8r zlib/1.2.5
Host: localhost:4567
Accept:application/json
Content-Type:application/json
Content-Length: 61

{file:{filename:"test.txt",md5sum:"ab3d2f"}}&This is a test.

リクエストの本文は有効なJSONではありません。URLエンコードされたフォームデータまたはマルチパートフォームデータでもありません。

JSONリクエストをファイルのアップロードと組み合わせる方法は明らかではありません。ここにいくつかのオプションがあります:

  • を使用するだけmultipart/form-dataです。つまり、Rubyコードと-Fカールするオプションを使用して、現在実行していることを実行します。
  • JSONの一部をメタデータに使用multipart/form-dataし、他の部分を未加工のアップロードファイルに使用します。
  • ファイルをbase64でエンコードしてJSONに埋め込みます。
  • 最初にメタデータをJSONとして投稿し、次にファイルをPOST本文にアップロードする、ある種の2リクエストワークフローを実行します。

非常に広くサポートされているので、おそらく最初のオプションを選択します。

于 2012-12-26T16:57:08.277 に答える
1

Ruby コードが壊れているようです。を忘れましたend:

post '/upload/:filename' do
  userdir = "./upload"
  FileUtils.mkdir_p(userdir) unless File.exists?(userdir)
  filename = File.join(userdir, params[:filename])
  datafile = params[:data]
  File.open(filename, 'wb') do |file|
    file.write(datafile[:tempfile].read)
  end
end
于 2012-12-25T15:16:35.133 に答える
0

これで、JSON を使用して以下の curl コマンドで動作させることができます。

curl -v -F 'json=[ {"filename": "@/Users/me/Desktop/test.pdf", "md5sum": "1496f9b6f42b7ed8260eadeb158c33f4", type": "generic"}, {"filename": "@/Users/me/Desktop/test2.pdf", "md5sum": "1496f9b6f42b7ed8260eadeb158c33f4", type": "generic"} ]' http://localhost:4567/upload

しかし、私は-F 'file=@/Users/me/Desktop/test.pdf'自分のファイルを POST するのに使用していないので、JSON オブジェクトを使用してサーバー側でファイルを取得するにはどうすればよいですか?

以下は機能しなくなりました。

tempfile = params[:file][:tempfile]
filename = params[:file][:filename]
dest = "#{userdir}/#{filename}"
FileUtils.cp(tempfile.path, dest) if not File.exists?(dest)
于 2012-12-27T06:25:39.013 に答える