python - 远程图像上传执行与开发服务器不同
问题描述
我的本地开发和实时开发服务器具有完全相同的代码和数据库(所有静态/媒体文件上传到 s3 存储)。
我有一个Post
带有image
字段的模型。我的帖子有一个图片上传字段,它通过 AJAX 上传到我的 s3 存储。在我的本地服务器和实时服务器中,图像成功上传,并且该图像在我的 s3 存储桶中的 url 被保存。因此,当我在本地服务器中提交帖子时,它不会再次上传,我只是在渲染图像时指向 URL。
但是,我的远程服务器不这样做。在我通过 AJAX 上传图像后,当我提交 Post 表单时,它会再次提交图像(它在我的浏览器上显示上传进度 - 3%、5%、10% 等...)。
知道为什么会这样吗?我的代码在这里:
楷模
class Post(models.Model):
image = models.FileField(null=True, blank=True)
意见
def post(request):
if request.user.is_authenticated():
form_post = PostForm(request.POST or None, request.FILES or None)
if form_post.is_valid():
instance = form_post.save(commit=False)
instance.user = request.user
...
if instance.image:
instance.imageURL = "https://s3.us-east-2.amazonaws.com/my-bucket/media/%s" % filename
instance.image = None #this prevents re-upload upon form submission
instance.save()
return HttpResponseRedirect('/')
else:
form_post = PostForm()
context = {
'form_post': form_post,
}
return render(request, 'post/post.html', context)
else:
return HttpResponseRedirect("/accounts/signup/")
ajax 视图
def upload_image(request):
random_filename = request.POST.get('random_filename')
if request.is_ajax():
if request.FILES:
img = request.FILES.get('image')
session = boto3.Session(
aws_access_key_id=AWS_ACCESS_KEY_ID,
aws_secret_access_key=AWS_SECRET_ACCESS_KEY,
)
s3 = session.resource('s3')
s3.Bucket('my-bucket').put_object(Key='media/%s' % random_filename, Body=img)
return HttpResponse()
else:
return HttpResponse()
模板
<input id="id_image" type="file" name="image" />
JS
$('input#id_image').on('change', function(e) {
var file = $('input[type=file]')[0].files[0];
var formData = new FormData();
$('.add_file_div h3').hide();
$('.add_file_label').css({
'border-radius': '5px',
'box-shadow': '5px',
});
var imagePath = URL.createObjectURL(e.target.files[0]);
var random_filename = random_string();
formData.append('image', file);
formData.append('csrfmiddlewaretoken', $("input[name='csrfmiddlewaretoken']").val());
formData.append('random_filename', random_filename);
$.ajax({
url: '/upload_image/',
data: formData,
type: 'POST',
contentType: false,
processData: false,
success: function(){
console.log('SUCCESSFULLY UPLOADED');
$('.add_file_label').css('opacity', '1');
$('.add_file_label').css('background', 'url(' + imagePath + ') scroll no-repeat center/cover');
$('.loading_spinner').css('visibility', 'hidden');
}
});
$('.add_file_label').css('background', 'url(' + imagePath + ') scroll no-repeat center/cover');
$('.add_file_label').css('opacity', '0.4');
$('.loading_spinner').css('visibility', 'visible');
console.log(imagePath);
$('.add_file_label').append('<input class="temp_s3_url" type="hidden" name="temp_s3_url">');
$('.temp_s3_url').val(random_filename);
$('input#id_imageURL').hide();
$('#delete_preview_image').show();
});
PS:我的 nginx 有client_max_body_size 200m;
所以这不是问题
解决方案
我认为同样的问题也可能在本地发生。但是当您在本地时,速度足够快,您看不到上传进度条。问题是,file
当您在 ajax 上传成功后,您应该清除您的字段
所以在里面
success: function(){
console.log('SUCCESSFULLY UPLOADED');
$('.add_file_label').css('opacity', '1');
$('.add_file_label').css('background', 'url(' + imagePath + ') scroll no-repeat center/cover');
$('.loading_spinner').css('visibility', 'hidden');
}
您将重置文件元素以使其成为空白值,否则它将与表单一起提交。
另一种选择可能是只给文件输入字段 a
id
而不是 aname
。如果input
元素没有附加名称,则不会与表单一起提交
推荐阅读
- javascript - Javascript setTimeout 立即在 React Native 中运行
- java - 杰克逊无法反序列化带有连字符的字段
- sql - 如何编写单个 SQL 查询以挑出具有多个条件的子组
- ruby-on-rails - 带有多个文件的 Rails file_field_tag 向控制器提供随机字符串
- haskell - blaze-html,Haskell,正确的 toHtml 用法?
- mysql - t2.micro EC2 实例运行速度过慢一段时间后恢复正常
- overheating - 戴尔l502x过热多年
- python - 用于抓取 excel 数据的 Python 脚本?
- java - Tesseract 错误空间识别(JavaCPP-Presets)
- c# - C# WPF 绑定深度/子对象路径