简体   繁体   English

Rails 4.2 - 将图像数据作为电子邮件附件发送而不保存图像

[英]Rails 4.2 - Send Image Data as Email Attachment Without Saving Image

My client app is an iOS app written in Swift. 我的客户端应用程序是用Swift编写的iOS应用程序。 In that iOS app, I convert an image to a Base64 encoded String and then send this String to my Rails server in the body of an HTTP request. 在那个iOS应用程序中,我将图像转换为Base64编码的字符串,然后将此字符串发送到HTTP请求正文中的Rails服务器。 This is my code for doing so: 这是我这样做的代码:

// Create a new URL request with the URL
let request: NSMutableURLRequest = NSMutableURLRequest(URL: url)

// Set the HTTP method to POST
request.HTTPMethod = "POST"

// Set the content type of the request to XML
request.setValue("application/xml", forHTTPHeaderField: "Content-Type")

// Convert the image to binary and then to a Base 64 Encoded String
let imageData:String = UIImagePNGRepresentation(image).base64EncodedStringWithOptions(nil)

// Set the HTTP Body of the request to the image
request.HTTPBody = NSData(base64EncodedString: imageData, options: nil)

In my Rails controller handling the request, I would like to retrieve the image and send it as an email attachment. 在处理请求的Rails控制器中,我想检索图像并将其作为电子邮件附件发送。 I do NOT want to save the image anywhere; 我不想把图像保存在任何地方; I just want to decode the image in memory and then somehow use that as the email attachment. 我只想解码内存中的图像,然后以某种方式将其用作电子邮件附件。

How can I retrieve the image data in my Rails controller and decode it in a way that would allow me to send it back as an email attachment? 如何在我的Rails控制器中检索图像数据并以允许我作为电子邮件附件发回的方式对其进行解码?

To retrieve the image data, I've tried using request.body.read , but this returns an empty String for some reason. 为了检索图像数据,我尝试使用request.body.read ,但由于某种原因,这会返回一个空字符串。

Thanks in advance for any help! 在此先感谢您的帮助!

EDIT: 编辑:

request.body.read was returning an empty String because I used a GET request. request.body.read返回一个空字符串,因为我使用了GET请求。 I've since learned that it's not a good idea to send an HTTP Body in a GET request, so I changed the method to POST. 我已经知道在GET请求中发送HTTP Body不是一个好主意,因此我将方法更改为POST。 Now request.body.read is returning my encoded String! 现在request.body.read正在返回我编码的String! I've also added the Content-Type header to the request. 我还在请求中添加了Content-Type标头。

Still, I can't figure out how to properly decode the HTTP Body and assign it to an image object of some sort. 不过,我无法弄清楚如何正确解码HTTP Body并将其分配给某种图像对象。

EDIT #2: 编辑#2:

I've managed to send the email attachment in my mailer using the following code: 我已设法使用以下代码在我的邮件程序中发送电子邮件附件:

attachments["file.png"] =
{
   mime_type: 'image/png',
   content: Base64.decode64(request.body.read)
}

Unfortunately, the PNG file cannot be opened when I receive it in the email. 不幸的是,当我在电子邮件中收到PNG文件时,无法打开它。 I don't know if the encoding translates well from Swift to Ruby. 我不知道编码是否可以很好地从Swift转换为Ruby。 I'll keep investigating. 我会继续调查。

EDIT #3: 编辑#3:

I removed the Base64 String encoding, and it's working great! 我删除了Base64字符串编码,它工作得很好! See my posted answer below. 请参阅下面我发布的答案。

I figured it out! 我想到了! I think the Base64 encoding/decoding isn't performed the same way on Swift and Ruby, so I decided to send the image as NSData without String encoding and then send it back, and that worked! 我认为Base64编码/解码在Swift和Ruby上的执行方式不同,所以我决定将图像作为NSData发送而不进行字符串编码,然后将其发送回来,这样就可以了! Here is my final code: 这是我的最终代码:

Swift 迅速

// Create a URL
let url:NSURL = NSURL(string: urlString)!

// Create a new URL request with the URL
let request: NSMutableURLRequest = NSMutableURLRequest(URL: url)

// Set the HTTP method to POST
// GET requests usually do not have an HTTP Body, and it's considered a very bad idea to include one in a GET request
request.HTTPMethod = "POST"

// Set the content type of the request to XML
request.setValue("application/xml", forHTTPHeaderField: "Content-Type")

// Convert the image to binary data
let imageData:NSData = UIImagePNGRepresentation(image)

// Set the HTTP Body of the request to the image
request.HTTPBody = imageData

// Create a new queue
let queue:NSOperationQueue = NSOperationQueue()

// Send the async request
NSURLConnection.sendAsynchronousRequest(request, queue: queue, completionHandler:
{ (response:NSURLResponse!, data:NSData!, error:NSError!) -> Void in
    println(response)
})

You can put this code in any method. 您可以将此代码放在任何方法中。

Ruby on Rails (Ruby 2.1.1 and Rails 4.2.0) Ruby on Rails(Ruby 2.1.1和Rails 4.2.0)

class ImageApiController < ApplicationController
  # Skip verifying the authenticity token since a form wasn't submitted; a web request was sent
  skip_before_filter :verify_authenticity_token, :only => [ :index ]

  def index
    params[:image] = request.body.read

    # Send the email
    UserMailer.image_attachment_email(params).deliver_now

    respond_to do |format|
      format.html
      format.js  { render plain: "Test" }
      format.xml { render plain: "Test" }
    end
  end
end

Then in UserMailer: 然后在UserMailer中:

class UserMailer < ApplicationMailer
  def image_attachment_email(params)
    attachments["image.png"] =
    {
      mime_type: 'image/png',
      content: params[:image]
    }

    # Send an email
    mail(to: "user@example.com", subject: "Image")
  end
end

So actually no Base64 String encoding was needed. 所以实际上不需要Base64字符串编码。 This code works great! 这段代码很棒!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM