这是一个非常长的问题,我非常感谢您的时间 - 希望您可以浏览的粘贴代码的大部分内容。
我一直致力于一个Django项目,该项目涉及用户上传图像(以及在将最终图像发送到服务器之前在客户端裁剪/旋转图像)。我找到并使用的JavaScript Image Cropper是Croppie,有一些基本的自定义。整个过程当时正在进行(大约4个月前,2017年11月),但后来我把项目放在了一边。
我最近选择了它,并且通过一些新的软件包更新,我对Django代码进行了一些小修改,但是没有触及JavaScript / HTML部分。我很惊讶当我尝试上传图片时,控制台抛出ConnectionAbortedError
并触发了一些下游错误,非常类似于question中遇到的错误。
完整的错误日志如下:
Traceback (most recent call last):
File "c:\users\xurub\appdata\local\programs\python\python36-32\Lib\wsgiref\handlers.py", line 138, in run
self.finish_response()
File "c:\users\xurub\appdata\local\programs\python\python36-32\Lib\wsgiref\handlers.py", line 180, in finish_response
self.write(data)
File "c:\users\xurub\appdata\local\programs\python\python36-32\Lib\wsgiref\handlers.py", line 274, in write
self.send_headers()
File "c:\users\xurub\appdata\local\programs\python\python36-32\Lib\wsgiref\handlers.py", line 332, in send_headers
self.send_preamble()
File "c:\users\xurub\appdata\local\programs\python\python36-32\Lib\wsgiref\handlers.py", line 255, in send_preamble
('Date: %s\r\n' % format_date_time(time.time())).encode('iso-8859-1')
File "c:\users\xurub\appdata\local\programs\python\python36-32\Lib\wsgiref\handlers.py", line 453, in _write
result = self.stdout.write(data)
File "c:\users\xurub\appdata\local\programs\python\python36-32\Lib\socketserver.py", line 775, in write
self._sock.sendall(b)
ConnectionAbortedError: [WinError 10053] An established connection was aborted by the software in your host machine
[03/Mar/2018 18:10:41] "GET /post_prod/ HTTP/1.1" 500 59
----------------------------------------
Exception happened during processing of request from ('127.0.0.1', 49806)
Traceback (most recent call last):
File "c:\users\xurub\appdata\local\programs\python\python36-32\Lib\wsgiref\handlers.py", line 138, in run
self.finish_response()
File "c:\users\xurub\appdata\local\programs\python\python36-32\Lib\wsgiref\handlers.py", line 180, in finish_response
self.write(data)
File "c:\users\xurub\appdata\local\programs\python\python36-32\Lib\wsgiref\handlers.py", line 274, in write
self.send_headers()
File "c:\users\xurub\appdata\local\programs\python\python36-32\Lib\wsgiref\handlers.py", line 332, in send_headers
self.send_preamble()
File "c:\users\xurub\appdata\local\programs\python\python36-32\Lib\wsgiref\handlers.py", line 255, in send_preamble
('Date: %s\r\n' % format_date_time(time.time())).encode('iso-8859-1')
File "c:\users\xurub\appdata\local\programs\python\python36-32\Lib\wsgiref\handlers.py", line 453, in _write
result = self.stdout.write(data)
File "c:\users\xurub\appdata\local\programs\python\python36-32\Lib\socketserver.py", line 775, in write
self._sock.sendall(b)
ConnectionAbortedError: [WinError 10053] An established connection was aborted by the software in your host machine
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "c:\users\xurub\appdata\local\programs\python\python36-32\Lib\wsgiref\handlers.py", line 141, in run
self.handle_error()
File "W:\Dropbox\Dropbox\work\Project\b2m\python-getting-started\venv\lib\site-packages\django\core\servers\basehttp.py", line 88, in handle_error
super(ServerHandler, self).handle_error()
File "c:\users\xurub\appdata\local\programs\python\python36-32\Lib\wsgiref\handlers.py", line 368, in handle_error
self.finish_response()
File "c:\users\xurub\appdata\local\programs\python\python36-32\Lib\wsgiref\handlers.py", line 180, in finish_response
self.write(data)
File "c:\users\xurub\appdata\local\programs\python\python36-32\Lib\wsgiref\handlers.py", line 274, in write
self.send_headers()
File "c:\users\xurub\appdata\local\programs\python\python36-32\Lib\wsgiref\handlers.py", line 331, in send_headers
if not self.origin_server or self.client_is_modern():
File "c:\users\xurub\appdata\local\programs\python\python36-32\Lib\wsgiref\handlers.py", line 344, in client_is_modern
return self.environ['SERVER_PROTOCOL'].upper() != 'HTTP/0.9'
TypeError: 'NoneType' object is not subscriptable
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "c:\users\xurub\appdata\local\programs\python\python36-32\Lib\socketserver.py", line 639, in process_request_thread
self.finish_request(request, client_address)
File "c:\users\xurub\appdata\local\programs\python\python36-32\Lib\socketserver.py", line 361, in finish_request
self.RequestHandlerClass(request, client_address, self)
File "c:\users\xurub\appdata\local\programs\python\python36-32\Lib\socketserver.py", line 696, in __init__
self.handle()
File "W:\Dropbox\Dropbox\work\Project\b2m\python-getting-started\venv\lib\site-packages\django\core\servers\basehttp.py", line 155, in handle
handler.run(self.server.get_app())
File "c:\users\xurub\appdata\local\programs\python\python36-32\Lib\wsgiref\handlers.py", line 144, in run
self.close()
File "c:\users\xurub\appdata\local\programs\python\python36-32\Lib\wsgiref\simple_server.py", line 35, in close
self.status.split(' ',1)[0], self.bytes_sent
AttributeError: 'NoneType' object has no attribute 'split'
表单生成为Django模型表单,其中'ProductPic1','ProductPic2'
是两个ImageField并导致当前问题。
class PostProduct(ModelForm):
image64_1 = forms.CharField(widget=forms.HiddenInput(),required=False)
image64_2 = forms.CharField(widget=forms.HiddenInput(),required=False)
class Meta:
model = Product
fields = ('title', 'TotalPrice','AvailabilityTimeStart', 'AvailabilityTimeEnd','FromCountry' ,'FromCity', 'ToCountry','ToCity',
'Description1','Description2','Description3','Description4','ProductPic1','ProductPic2','ProductLink','AdditionalComments', 'image64_1','image64_2',)
# 'x1', 'y1', 'width1','height1', 'x2', 'y2', 'width2','height2',)
widgets = {
'FromCountry': autocomplete.Select2(url='country-autocomplete'),
'ToCountry': autocomplete.Select2(url='country-autocomplete'),
'FromCity': autocomplete.Select2(url='city-autocomplete', forward=['FromCountry']),
'ToCity': autocomplete.Select2(url='city-autocomplete', forward=['ToCountry']),
'AvailabilityTimeStart': DateInput(),
'AvailabilityTimeEnd':DateInput(),
#'AvailabilityTimeStart': SelectDateWidget(empty_label=("Choose Year", "Choose Month", "Choose Day"),),
}
模板的位置是:
<form method="post" enctype="multipart/form-data" id="post_form">
{% csrf_token %}
{{ form | crispy }}
<div>
<button type="submit" class="w3-button w3-dark-grey " name="post_prod">Submit!</button>
</div>
</form>
<!-- MODAL TO CROP THE IMAGE -->
<div class="modal fade" id="modalCrop">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
<h4 class="modal-title">Crop the photo</h4>
</div>
<div id="photoCanvas" class="modal-body">
<img src="" id="image" style="max-width: 100%;">
</div>
<div class="modal-footer">
<div class="btn-group pull-left" role="group">
<!-- <button type="button" class="btn btn-default js-zoom-in">
<span class="fa fa-plus"></span>
</button>
<button type="button" class="btn btn-default js-zoom-out">
<span class="fa fa-minus"></span>
</button>
-->
<button type="button" class="btn btn-default left-rotate">
<span class="fa fa-undo"></span>
</button>
<button type="button" class="btn btn-default right-rotate">
<span class="fa fa-repeat"></span>
</button>
</div>
<button type="button" class="btn btn-default" data-dismiss="modal">Nevermind</button>
<button type="button" class="btn btn-primary js-crop-and-upload">Crop and upload</button>
</div>
</div>
</div>
</div>
JavaScripts:
<link rel="stylesheet" href="{% static 'css/bootstrap.css' %}" />
<link rel="stylesheet" href="{% static 'css/landing.css' %}" />
<link rel="stylesheet" href="{% static 'css/rotate.css' %}" />
<link rel="stylesheet" href="{% static 'css/croppie.css' %}" />
<!-- <script src="{% static 'js/cropper.min.js' %}"></script> -->
<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
<!-- <script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script> -->
<!-- <script src="https://code.jquery.com/jquery-1.11.3.min.js"></script>
<link href="https://cdn.rawgit.com/fengyuanchen/cropper/v2.0.1/dist/cropper.min.css" rel="stylesheet">
<script src="https://cdn.rawgit.com/fengyuanchen/cropper/v2.0.1/dist/cropper.min.js"></script> -->
<script src="{% static 'js/bootstrap.min.js' %}"></script>
<script src="{% static 'js/croppie.js' %}"></script>
// croppie
var el = document.getElementById('image');
var picNum;
var piclink;
var vanilla;
$("#id_ProductPic1").change(function () {
if (this.files && this.files[0]) {
var reader = new FileReader();
vanilla = new Croppie(el, {
viewport: { width: 350, height: 350 },
boundary: { width: 500, height: 500 },
showZoomer: true,
enableOrientation: true
});
reader.onload = function (e) {
piclink = e.target.result;
$("#image").attr("src", piclink);
$("#modalCrop").modal("show");
picNum = 1;
}
reader.readAsDataURL(this.files[0]);
}
});
$("#id_ProductPic2").change(function () {
if (this.files && this.files[0]) {
var reader = new FileReader();
vanilla = new Croppie(el, {
viewport: { width: 350, height: 350 },
boundary: { width: 500, height: 500 },
showZoomer: true,
enableOrientation: true
});
reader.onload = function (e) {
piclink = e.target.result;
$("#image").attr("src",piclink);
$("#modalCrop").modal("show");
picNum = 2;
}
reader.readAsDataURL(this.files[0]);
}
});
$("#modalCrop").on("shown.bs.modal", function () {
vanilla.bind({
url: piclink,
});
}).on("hidden.bs.modal", function () {
vanilla.destroy();
});
var angle = 0;
$('.right-rotate').on('click', function() {
vanilla.rotate(90);
});
$('.left-rotate').on('click', function() {
vanilla.rotate(270);
});
// croppie
/* SCRIPT TO COLLECT THE DATA AND POST TO THE SERVER */
$(".js-crop-and-upload").click(function () {
if (picNum == 1){
vanilla.result('base64','jpeg').then(function(img) {
// do something with cropped blob
$("#id_image64_1").val(img);
})}
else if (picNum == 2){
vanilla.result('base64','jpeg').then(function(img) {
// do something with cropped blob
$("#id_image64_2").val(img);
})};
$("#modalCrop").modal("hide");
});
有关错误的更多信息: 1.即使在抛出错误之后,只要表格的其他部分被正确填写,它仍然可以提交和发布 - 只是没有附加到帖子的图像。 2.当我完成选择要上传的文件/图像时,会抛出错误。单击选择文件按钮 - 选择图像 - 单击打开 - 错误 - 图像打开,您可以执行裁剪和旋转 - 单击裁剪和上传 - 模态关闭并返回到表单 - 继续提交表单 - 没有图像数据传递给服务器。
我很困惑,因为我在4个月前工作时所做的改变很少,现在还没有工作,特别是我很确定我根本没有触及JavaScript部分。
Django版本可能已经改变 - 我现在正在使用 Django 1.11.7 ,但我不记得之前我使用过的是什么。另外,虽然我不太熟悉JavaScripts,但似乎没有任何与连接相关的东西 - 在客户端不是所有的东西都完成了吗?
如果您需要更多信息以帮助查明问题,请与我们联系。
提前致谢!