質問編集履歴

2

問題部分を追記

2018/04/01 23:43

投稿

tacro
tacro

スコア23

test CHANGED
@@ -1 +1 @@
1
- [Javascript] Rails5ユーザーがトリミングした画像を、S3に直接アップロードしたい
1
+ [Javascript] Rails5ユーザーがトリミングした画像を、S3に直接アップロードしたい
test CHANGED
@@ -34,7 +34,9 @@
34
34
 
35
35
  ⑴元の画像の代わりに、トリミングした画像データをs3にアップロードできません。
36
36
 
37
- を参考に、以下のようにコードを書いたのですが、トリミングされる前の画像データがアップされてしまいます。
37
+ 以下のようにコードを書いたのですが、トリミングされる前の画像データがアップされてしまいます。
38
+
39
+ **【追記】2回submitボタンを押すと、2回目の送信ではトリミング後の画像がアップされることがわかりました。**(詳細は後述します。)
38
40
 
39
41
 
40
42
 
@@ -268,6 +270,72 @@
268
270
 
269
271
 
270
272
 
273
+ #試してみたこと
274
+
275
+ 以下のようにコードを書き換えて、コンソールでオンクリックアクション時のdata.originalFiles[0]の中身を確認すると、ちゃんとトリミング後の画像になっていました。
276
+
277
+ 一度submitボタンを押してアップロードが完了した後、もう一度クリックすると、トリミング後の画像がs3にアップされることがわかりました。
278
+
279
+ なぜ1度目のクリックで行かないのでしょうか…
280
+
281
+
282
+
283
+ ```Javascript
284
+
285
+ $(function() {
286
+
287
+ $('.directUpload').find("input:file").each(function(i, elem) {
288
+
289
+ ...
290
+
291
+ submitButton.on('click', function(){
292
+
293
+ // crop のデータを取得
294
+
295
+ $('#crop_img').cropper('getCroppedCanvas').toBlob(function (blob){
296
+
297
+ data.files[0] = new File([blob], data.files[0].name);
298
+
299
+ data.originalFiles[0] = data.files[0];
300
+
301
+ })
302
+
303
+ data.submit();
304
+
305
+ });
306
+
307
+ },
308
+
309
+
310
+
311
+ ....
312
+
313
+
314
+
315
+ done: function(e, data) {
316
+
317
+ ...
318
+
319
+ //アップロード完了時のフォームの提出をキャンセル
320
+
321
+ //$('.directUpload').submit(); //submit a form
322
+
323
+ },
324
+
325
+ ....
326
+
327
+
328
+
329
+
330
+
331
+ });
332
+
333
+ });
334
+
335
+
336
+
337
+ ```
338
+
271
339
 
272
340
 
273
341
  ### 補足情報(FW/ツールのバージョンなど)

1

発生している問題点を修正

2018/04/01 23:43

投稿

tacro
tacro

スコア23

test CHANGED
File without changes
test CHANGED
@@ -4,29 +4,41 @@
4
4
 
5
5
  Rails5を使って、ユーザーが画像を選択し、自由にトリミングした上で投稿できる機能を実装中です。
6
6
 
7
- Carrierwaveを用いた通常の実装はできたのですが、サーバーにherokuを使用しているのでアップロードが遅くなってしまうことを懸念し、以下の記事参考に、S3に直接アップロードする方法を取ろうとしています。
7
+ Carrierwaveを用いた通常の実装はできたのですが、サーバーにherokuを使用しているのでアップロードが遅くなってしまうことを懸念し、jQuery file-upload使用してクライアントサイドからS3に直接アップロードする方法を取ろうとしています。
8
+
9
+
10
+
11
+ 画像をトリミングしない場合は問題なくこの方法で実装できたのですが、トリミングさせる際に、以下の問題が生じました。
12
+
13
+ JSの経験に乏しいので、ご助言いただきたいです…
14
+
15
+
16
+
17
+ 参考記事:
8
18
 
9
19
  [Direct to S3 Image Uploads in Rails
10
20
 
11
21
  ](https://devcenter.heroku.com/articles/direct-to-s3-image-uploads-in-rails)
12
22
 
23
+ [Direct Upload of Image to S3 after Manual Cropping with Cropper.js](https://stackoverflow.com/questions/37910998/direct-upload-of-image-to-s3-after-manual-cropping-with-cropper-js)
24
+
13
- 画像をトリミングしない場合は問題なくこの方法で実装できたのですが、トリミングさせる際に、以下の問題が生じました。
25
+ [jQuery-File-Upload](https://github.com/blueimp/jQuery-File-Upload/wiki/Options#singlefileuploads)
14
-
15
- JSの経験に乏しいので、ご助言いただきたいです…
26
+
27
+
28
+
29
+
16
30
 
17
31
 
18
32
 
19
33
  ### 発生している問題・エラーメッセージ
20
34
 
21
- ⑴元の画像の代わりに、トリミングした画像データをs3にアップロードできない
35
+ ⑴元の画像の代わりに、トリミングした画像データをs3にアップロードできません。
22
-
36
+
23
- [Direct Upload of Image to S3 after Manual Cropping with Cropper.js
37
+ を参考に、以下のようにコードを書いたのですが、トリミングされる前の画像データがアップされてしまいます。
24
-
25
- Ask Question](https://stackoverflow.com/questions/37910998/direct-upload-of-image-to-s3-after-manual-cropping-with-cropper-js)を参考に、以下のようにコードを書いたのですが、トリミングされる前の画像データがアップされてしまいます。
38
+
26
-
27
-
28
-
39
+
40
+
29
- ⑵また、このコードだと、ボタンてもページが遷移せずpostオブジェクトが作成されません
41
+ ⑵また、このコードだと、画像選択直した場合投稿二つ作成されてしいます
30
42
 
31
43
 
32
44
 
@@ -34,164 +46,174 @@
34
46
 
35
47
  $(function() {
36
48
 
37
- $('.directUpload').find("input:file").each(function(i, elem) {
38
-
39
- var fileInput = $(elem);
40
-
41
- var form = $(fileInput.parents('form:first'));
42
-
43
- var submitButton = form.find('input[type="submit"]');
44
-
45
- var progressBar = $("<div class='bar'></div>");
46
-
47
- var barContainer = $("<div class='progress'></div>").append(progressBar);
48
-
49
- fileInput.after(barContainer);
50
-
51
- fileInput.fileupload({
52
-
53
- fileInput: fileInput,
54
-
55
- url: form.data('url'),
56
-
57
- type: 'POST',
58
-
59
- autoUpload: true,
60
-
61
- formData: form.data('form-data'),
62
-
63
- paramName: 'file', // S3 does not like nested name fields i.e. name="user[avatar_url]"
64
-
65
- dataType: 'XML', // S3 returns XML if success_action_status is set to 201
66
-
67
- replaceFileInput: false,
68
-
69
-
70
-
71
- add: function(e, data){
72
-
73
- if (data.files && data.files[0]) {
74
-
75
- console.log("called");
76
-
77
- var reader = new FileReader();
78
-
79
- reader.onload = function(e) {
80
-
81
- $('.preview').empty();
82
-
83
- $('.preview').append($('<img>').attr({// insert preview image
84
-
85
- src: e.target.result,
86
-
87
- id: "crop_img",
88
-
89
- title: data.files[0].name
90
-
91
- }));
92
-
93
- $('#crop_img').cropper() // initialize cropper on preview image
94
-
95
- };
96
-
97
- reader.readAsDataURL(data.files[0]);
98
-
99
- };
100
-
101
-
102
-
103
- $('#_submit').on('click', function(){
104
-
105
- // crop のデータを取得
106
-
107
- $('#crop_img').cropper('getCroppedCanvas').toBlob(function (blob){
108
-
109
- var croppedFile = new File([blob], data.files[0].name);
110
-
111
- data.files[0] = croppedFile;
112
-
113
- data.originalFiles[0] = data.files[0];
114
-
115
- })
116
-
117
- data.submit();
118
-
119
- });
120
-
121
- },
122
-
123
-
124
-
125
- progressall: function (e, data) {
126
-
127
- var progress = parseInt(data.loaded / data.total * 100, 10);
128
-
129
- progressBar.css('width', progress + '%')
130
-
131
- },
132
-
133
- start: function (e) {
134
-
135
- submitButton.prop('disabled', true);
136
-
137
-
138
-
139
- progressBar.
140
-
141
- css('background', 'black').
142
-
143
- css('display', 'block').
144
-
145
- css('width', '0%').
146
-
147
- text("Loading...");
148
-
149
- },
150
-
151
- done: function(e, data) {
152
-
153
- submitButton.prop('disabled', false);
154
-
155
- progressBar.text("Uploading done");
156
-
157
-
158
-
159
- // extract key and generate URL from response
160
-
161
- var key = $(data.jqXHR.responseXML).find("Key").text();
162
-
163
- var url = '//' + form.data('host') + '/' + key;
164
-
165
-
166
-
167
- // create hidden field
168
-
169
- var input = $("<input />", { type:'hidden', name: fileInput.attr('name'), value: url })
170
-
171
- form.append(input);
172
-
173
- },
174
-
175
- fail: function(e, data) {
176
-
177
- submitButton.prop('disabled', false);
178
-
179
-
180
-
181
- progressBar.
182
-
183
- css("background", "red").
184
-
185
- text("Failed");
186
-
187
- }
188
-
189
- });
49
+ $('.directUpload').find("input:file").each(function(i, elem) {
50
+
51
+ var fileInput = $(elem);
52
+
53
+ var form = $(fileInput.parents('form:first'));
54
+
55
+ var submitButton = form.find('input[type="submit"]');
56
+
57
+ var progressBar = $("<div class='bar'></div>");
58
+
59
+ var barContainer = $("<div class='progress'></div>").append(progressBar);
60
+
61
+ fileInput.after(barContainer);
62
+
63
+ fileInput.fileupload({
64
+
65
+ fileInput: fileInput,
66
+
67
+ url: form.data('url'),
68
+
69
+ type: 'POST',
70
+
71
+ autoUpload: false,
72
+
73
+ formData: form.data('form-data'),
74
+
75
+ paramName: 'file', // S3 does not like nested name fields i.e. name="user[avatar_url]"
76
+
77
+ dataType: 'XML', // S3 returns XML if success_action_status is set to 201
78
+
79
+ replaceFileInput: true,
80
+
81
+ acceptFileTypes: /(.|/)(gif|jpe?g|png)$/i,
82
+
83
+
84
+
85
+ add: function(e, data){
86
+
87
+ if (data.files && data.files[0]) {
88
+
89
+ console.log("called");
90
+
91
+ var reader = new FileReader();
92
+
93
+ reader.onload = function(e) {
94
+
95
+ $('.preview').empty();
96
+
97
+ $('.preview').append($('<img>').attr({// insert preview image
98
+
99
+ src: e.target.result,
100
+
101
+ id: "crop_img",
102
+
103
+ title: data.files[0].name
104
+
105
+ }));
106
+
107
+ $('#crop_img').cropper() // initialize cropper on preview image
108
+
109
+ };
110
+
111
+ reader.readAsDataURL(data.files[0]);
112
+
113
+ };
114
+
115
+
116
+
117
+ submitButton.on('click', function(){
118
+
119
+ // crop のデータを取得
120
+
121
+ $('#crop_img').cropper('getCroppedCanvas').toBlob(function (blob){
122
+
123
+ data.files[0] = new File([blob], data.files[0].name);
124
+
125
+ data.originalFiles[0] = data.files[0];
126
+
127
+ })
128
+
129
+ data.submit();
130
+
131
+ });
132
+
133
+ },
134
+
135
+
136
+
137
+ progressall: function (e, data) {
138
+
139
+ var progress = parseInt(data.loaded / data.total * 100, 10);
140
+
141
+ progressBar.css('width', progress + '%')
142
+
143
+ },
144
+
145
+
146
+
147
+ start: function (e) {
148
+
149
+ submitButton.prop('disabled', true);
150
+
151
+
152
+
153
+ progressBar.
154
+
155
+ css('background', 'black').
156
+
157
+ css('display', 'block').
158
+
159
+ css('width', '0%').
160
+
161
+ text("Loading...");
162
+
163
+ },
164
+
165
+
166
+
167
+ done: function(e, data) {
168
+
169
+ submitButton.prop('disabled', false);
170
+
171
+ progressBar.text("Uploading done");
172
+
173
+
174
+
175
+ // extract key and generate URL from response
176
+
177
+ var key = $(data.jqXHR.responseXML).find("Key").text();
178
+
179
+ var url = '//' + form.data('host') + '/' + key;
180
+
181
+
182
+
183
+ // create hidden field
184
+
185
+ var input = $("<input />", { type:'hidden', name: fileInput.attr('name'), value: url })
186
+
187
+ form.append(input);
188
+
189
+ $('.directUpload').submit(); //submit a form
190
+
191
+ },
192
+
193
+
194
+
195
+ fail: function(e, data) {
196
+
197
+ submitButton.prop('disabled', false);
198
+
199
+
200
+
201
+ progressBar.
202
+
203
+ css("background", "red").
204
+
205
+ text("Failed");
206
+
207
+ }
190
208
 
191
209
  });
192
210
 
193
211
  });
194
212
 
213
+ });
214
+
215
+
216
+
195
217
  ```
196
218
 
197
219
 
@@ -240,61 +262,7 @@
240
262
 
241
263
 
242
264
 
243
- ### 試したこと
244
-
245
-
246
-
247
- オンクリックアクションの部分を、以下のように変えて試してみました。
248
-
249
-
250
-
251
- ```javascript
252
-
253
- ...
254
-
255
- $('#_submit').on('click', function(){
256
-
257
- // crop のデータを取得
258
-
259
- $('#crop_img').cropper('getCroppedCanvas').toBlob(function (blob){
260
-
261
- var croppedFile = new File([blob], data.files[0].name);
262
-
263
- data.files[0] = croppedFile;
264
-
265
- data.originalFiles[0] = data.files[0];
266
-
267
- })
268
-
269
- data.submit();
270
-
271
- $('.directUpload').submit();
272
-
273
- });
274
-
275
- ...
276
-
277
- ```
278
-
279
-
280
-
281
- すると、オブジェクトは作成され、ページも遷移するのですが、アップロードされる画像が依然として元のままになってしまいます。
282
-
283
- また、画像を`<%= image_tag post.image_name %>`で描画しようとすると、以下のエラーが発生します。
284
-
285
- アセット名が空白になってしまうようです。
286
-
287
-
288
-
289
- ```
290
-
291
- The asset "" is not present in the asset pipeline.
292
-
293
- ```
294
-
295
-
296
-
297
- どうすれば、トリミング後の画像を、s3にアップしかつ描画することができるでしょうか?
265
+ どうすれば、トリミング後の画像を、s3にアップすることができるでしょうか?
298
266
 
299
267
  アドバイスをよろしくお願いいたします。
300
268