Python Requests POST图片二进制失败,如何结合JS代码修复?
问题描述
我用Python Requests写了一段代码提交图片数据到指定URL,但图片一直上传失败,推测核心问题是没正确传递图片二进制文件。附上我的Python代码和目标网站的JavaScript上传逻辑,求帮忙修复代码。
我的Python代码
def change_img(self, good_uid, image): data = { "file": image, "old_image_hosting_url": "", "goods_uid": good_uid, "image_type": "main", } headers = { "Accept": "text/html, */*; q=0.01", "Referer": self.BASE_URL + f"/mall/admin/admin_goods_image_upload.php?image_type=main&goods_uid={good_uid}&image_id=main_0", "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.0.0 Safari/537.36", "X-Requested-With": "XMLHttpRequest", } response = self.session.post( url=self.BASE_URL + "/mall/admin/admin_goods_image_upload_ok.php", headers=headers, data=data, ) if response.status_code == 200: print(response.elapsed.total_seconds()) return True resp = requests.get(url=url, stream=True) if resp.status_code == 200: img = np.asarray(bytearray(resp.raw.read()), dtype="uint8") decoded_img = cv2.imdecode(img, flags=1) bg_removed_img = remove(decoded_img) retval, buffer = cv2.imencode(".png", bg_removed_img) change_img(... buffer)
目标网站的JavaScript上传逻辑
var goods_uid = "145690"; var image_id = "main_0"; var image_type = "main"; var image_hosting_url = "https://tmgdisk01.cafe24.com/"; var pmode = ""; var old_image_hosting_url = ""; if (image_id) { old_image_hosting_url = $("#" + image_id, opener.document).attr("hosting"); old_image_hosting_url = old_image_hosting_url.replace( "{HOST}", image_hosting_url, ); } $(document).ready(function () { var fileTarget = $(".filebox .upload-hidden"); fileTarget.on("change", function () { if (window.FileReader) { // 파일명 추출 var filename = $(this)[0].files[0].name; } else { // Old IE 파일명 추출 var filename = $(this).val().split("/").pop().split("\\").pop(); } $(this).siblings(".upload-name").val(filename); var fd = new FormData(); var files = $("#input_file")[0].files[0]; fd.append("file", files); fd.append("old_image_hosting_url", old_image_hosting_url); fd.append("goods_uid", goods_uid); fd.append("image_type", image_type); $.ajax({ url: "admin_goods_image_upload_ok.php", type: "post", data: fd, contentType: false, processData: false, success: function (response) { //console.log("==> aaaa : "+response); //console.log("==> pmode : "+pmode); //console.log("==> goods_uid : "+goods_uid); if (response && response != "null") { try { var result = jQuery.parseJSON(response); var status = result["status"]; var image_url = result["url"]; var msg = result["msg"]; var image_url2 = ""; if ("undefined" != typeof image_url) image_url2 = image_url.replace("{HOST}/", image_hosting_url); if (status == "success" && image_url) { if (goods_uid && image_id) { var parent_input = image_id + "_input"; $("#" + image_id, opener.document).attr("src", image_url2); $("#" + image_id, opener.document).attr("hosting", image_url); $("#" + parent_input, opener.document).val(image_url2); opener.parent.image_save( image_type, goods_uid, image_id, "", "", ); window.close(); } else if (pmode == "desc" && goods_uid) { opener.parent.image_load(goods_uid, image_url2); window.close(); } else { $("#result").html(msg + "<br>→ 이미지경로 : " + image_url2); } } else { //$(".result").html(result.msg+"<br>→ 파일 업로드가 실패되었습니다. FTP 접속정보를 확인해주세요. : "+image_url2); $("#result").html(msg); } } catch (e) { $("#result").html("@@" + response); } } else { alert("파일 업로드가 실패되었습니다."); } }, }); }); //preview image });
修复方案
你的代码核心问题在于:
- 直接用
data参数传递文件,而非模拟表单文件上传的files参数(对应JS里的FormData) - 未指定文件名和文件类型,后端无法正确识别上传的文件
- 手动处理
Content-Type会导致格式错误
修复后的change_img函数
def change_img(self, good_uid, image_buffer): # 用files参数构造文件上传表单,指定文件名、字节数据和MIME类型 files = { "file": ("image.png", image_buffer.tobytes(), "image/png") } # 其他表单字段放在data里 data = { "old_image_hosting_url": "", "goods_uid": good_uid, "image_type": "main", } headers = { "Accept": "text/html, */*; q=0.01", "Referer": self.BASE_URL + f"/mall/admin/admin_goods_image_upload.php?image_type=main&goods_uid={good_uid}&image_id=main_0", "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.0.0 Safari/537.36", "X-Requested-With": "XMLHttpRequest", } # 不要手动设置Content-Type,requests会自动生成正确的multipart/form-data头 response = self.session.post( url=self.BASE_URL + "/mall/admin/admin_goods_image_upload_ok.php", headers=headers, files=files, data=data, ) # 打印响应内容方便排查错误 print(response.text) if response.status_code == 200: print(response.elapsed.total_seconds()) return True return False
调用部分调整
resp = requests.get(url=url, stream=True) if resp.status_code == 200: img = np.asarray(bytearray(resp.raw.read()), dtype="uint8") decoded_img = cv2.imdecode(img, flags=1) bg_removed_img = remove(decoded_img) retval, buffer = cv2.imencode(".png", bg_removed_img) # 传递buffer的字节数据给change_img change_img(..., buffer)
关键修复说明
- 文件传递方式:JS用
FormData上传文件,对应Python requests必须用files参数,格式为{"字段名": (文件名, 字节数据, MIME类型)} - 文件名与类型:指定文件名(可自定义)和
image/png类型,确保后端能正确解析文件 - Content-Type处理:无需手动设置,requests会自动生成符合要求的
multipart/form-data头,和JS里的contentType: false逻辑一致 - 响应调试:添加
print(response.text)可查看后端返回的具体错误信息,方便进一步排查问题
内容的提问来源于stack exchange,提问作者shim robin
相关产品推荐
相关产品推荐

