webエンジニアの日常

RubyやPython, JSなど、IT関連の記事を書いています

Rubyでフォルダ内のファイルをpost送信する

こんにちは、さもです。

動画投稿webサービス作ったはいいけど、手元のファイルすべてをポチポチと画面からアップロードするのめんどくさいな

ってときありますよね。

先日こういうのを作ったので必要になりました。

www.uosansatox.biz

そんな要望にお答えする、「フォルダ内の全てのファイルをpost送信する」スクリプトを実装しました。

スポンサーリンク

require 'net/https'

@uri = URI.parse("ポストするURL")
@http = Net::HTTP.new(@uri.host, @uri.port)
@http.use_ssl = true
@http.verify_mode = OpenSSL::SSL::VERIFY_NONE

def apipost(filename)
  req = Net::HTTP::Post.new(@uri.path)
  File.open("./up_test/#{filename}") do |file|
    data = [
      ["image", file],
    ]
    req.set_form(data, "multipart/form-data")
    res = @http.request(req)
  end
end


Dir.glob("./up_test/*").each do |filename|
  apipost(filename)
end

こんな感じです。

解説

require 'net/https'

@uri = URI.parse("ポストするURL")
@http = Net::HTTP.new(@uri.host, @uri.port)
@http.use_ssl = true
@http.verify_mode = OpenSSL::SSL::VERIFY_NONE

インスタンス化して、ssl使うなど、もろもろ設定しておきます

def apipost(filename)
  req = Net::HTTP::Post.new(@uri.path)
  File.open("./up_test/#{filename}") do |file|
    data = [
      ["image", file],
    ]
    req.set_form(data, "multipart/form-data")
    res = @http.request(req)
  end
end

ポスト送信を実際に行ってくれるメソッドです。

ポイントは、set_form_dateではなく、set_dateメソッドでmultipartを設定することです。

"multipart/form-data"を設定しないと、ファイルが送信されてもモデルに入れてくれません。これは画面を作るときも一緒ですね。

data配列に、<input type="text">で入力したような値を入れたい場合も、

    data = [
      ["comment", "テストです"],
      ["image", file],
    ]

みたいにすればOKです。

Dir.glob("./up_test/*").each do |filename|
  apipost(filename)
end

Dir.glob("./up_test/*")でファイルの配列を返してくれるのですが、./up_test/も含まれているので、そのままメソッドに渡します

このプログラムではいきなりpostしているので、csrfにひっかかります。

なので、サーバサイドではkip_before_action :verify_authenticity_tokenをしておくのがいいでしょう

読者登録はこちらからお願いします。