使用Fetch发送图片调用MathPix API报仅支持HTTP(S)协议问题
问题根因
报错是URL.createObjectURL()生成的blob临时URL导致的,和MathPix服务端机制无关:
- blob URL是浏览器本地生成的、仅当前页面上下文可访问的本地内存资源引用,协议为
blob:,不属于公网可访问的HTTP/HTTPS资源 - MathPix接口收到
src字段传入的URL后,会从自身服务端发起请求拉取对应图片,它完全访问不到你浏览器本地内存里的blob资源,自然会抛出「仅支持HTTP(S)协议」的错误。
解决方案
你不需要提前把文件存储到数据库,有两种可直接落地的实现方式:
方案1:直接传base64格式图片内容给MathPix(前端改造成本最低)
把本地选中的图片文件转成base64字符串,直接放到src字段传给接口即可,MathPix原生支持base64格式图片输入,修改对应逻辑代码如下:
function checkExtension(event) { var input = event.srcElement; var fileName = input.files[0].name; var extension = fileName.substr(fileName.lastIndexOf(".")); var allowedExtensionsRegx = /(\.jpg|\.jpeg|\.png|\.gif)$/i; var file = document.getElementById(event.target.name) if (allowedExtensionsRegx.test(extension) == true) { file.setAttribute("class", "btn-success p-2 rounded") const image = input.files[0]; // 替换原先生成blob URL的逻辑,转base64 const reader = new FileReader(); reader.onload = function(e) { snip_request(e.target.result) } reader.readAsDataURL(image); } else { file.setAttribute("class", "btn-danger p-2 rounded") } } function snip_request(image_base64){ if(image_base64) { const appId = "XXXXXXXXXXXXXXXXX"; const appKey = "YYYYYYYYYYYYYYYY"; var url = "https://api.mathpix.com/v3/latex"; var _data = { "src": image_base64, // 直接传入base64结果 "formats": "text", "data_options": { "include_asciimath": true, "include_latex": true } } var _header = { "content-type": "application/json", "app_id": appId, "app_key": appKey } fetch(url, { method: "POST", body: JSON.stringify(_data), headers: _header }) .then(response => response.json()) .then(json => console.log(json)); } }
方案2:走Django后端做中转(安全性更高)
如果不想把MathPix的appId和appKey直接暴露在前端代码里,可以先把选中的图片通过POST请求传到自己的Django后端,后端临时接收文件后,要么直接把文件内容转发给MathPix接口,要么生成一个可临时访问的HTTP/HTTPS图片URL再传给MathPix,处理完成后把LaTeX结果返回给前端即可。
注意:如果选择方案1的base64传参方式,普通大小的公式截图完全不会超过MathPix接口的大小限制,不需要额外做压缩处理。
内容的提问来源于stack exchange,提问作者Wincij
相关产品推荐
相关产品推荐

