微信公众号开发使用weui上传图片

先说一下遇到的问题,

1.刚开始在开发阶段直接前台用ajax调接口上传图片没问题,可是到了正式服务器部署时,问题出现了。好像是无法跨域(可能是服务器域名化了的原因),但是后台接口方法中已经添加了允许跨域请求的代码:

//跨域请求
        response.setHeader("Access-Control-Allow-Origin", "*");

2.于是,调整方案,前台 ajax 上传文件提交到后台,在后台调用接口来完成文件上传,代码写完测试时又发现问题了,大一点的图片传到后台时接收不到,部分android手机上传的图片后台也接收不到。

最终的解决方案:

前台使用fetch发起请求,并且将图片转换成  base64字符串再提交到后台,后台解析成图片调用接口完成图片上传。

注意:部分Android手机出现点击图片上传按钮无响应的情况,经排查是下面这段代码的问题。

<input class="weui_uploader_input" name="file" type="file" id="up_file" accept="image/jpg,image/jpeg,image/png,image/gif" multiple />  

部分Android手机不支持  H5的multiple  属性,去掉即可(去掉之后在选取图片时一次只能选择一张)

一、前端上传图片:

前端使用 weui 来选取图片。

<div class="weui_uploader z_photo1"> 
   <div class="weui_uploader_bd"> 
    <ul class="weui_uploader_files" id="img2x"> 
    </ul> 
    <div class="weui_uploader_input_wrp"> 
     <input class="weui_uploader_input" name="file" type="file" id="up_file" accept="image/jpg,image/jpeg,image/png,image/gif" multiple /> 
    </div> 
   </div> 
  </div>

js部分,通过fetch将选取到的图片发给后台处理

$(function() {
    // 允许上传的图片类型
    var allowTypes = ['image/jpg', 'image/jpeg', 'image/png', 'image/gif'];
    // 1024KB*10),也就是 10MB
    var maxSize = 1024 * 10 * 1024;
    // 图片最大宽度
    var maxWidth = 9000;
    // 最大上传图片数量
    var maxCount = 6;
    $('#up_file').on('change',
    function(event) {
        var files = event.target.files;
        //console.log(files);
        //console.log("--files.length--",files.length);
        // 如果没有选中文件,直接返回
        if (files.length === 0) {
            return;
        }
        for (var i = 0,
        len = files.length; i < len; i++) {
            var file = files[i];
            var reader = new FileReader();
            // 如果类型不在允许的类型范围内
            if (allowTypes.indexOf(file.type) === -1) {
                $.weui.alert({
                    text: '该类型不允许上传'
                });
                continue;
            }
            if (file.size > maxSize) {
                $.weui.alert({
                    text: '图片太大,不允许上传'
                });
                continue;
            }
            if ($('.weui_uploader_file').length >= maxCount) {
                $.weui.alert({
                    text: '最多只能上传' + maxCount + '张图片'
                });
                return;
            }
            //console.log(file.name);
            var _canvas;
            reader.onload = function(e) {
                //console.log('--render.onload-');
                var img = new Image();
                img.onload = function() {
                    //console.log('--img.onload-');
                    // 不要超出最大宽度
                    var w = Math.min(maxWidth, img.width);
                    // 高度按比例计算
                    var h = img.height * (w / img.width);
                    var canvas = document.createElement('canvas');
                    var ctx = canvas.getContext('2d');
                    // 设置 canvas 的宽度和高度
                    canvas.width = w;
                    canvas.height = h;
                    ctx.drawImage(img, 0, 0, w, h);
                    var base64 = canvas.toDataURL('image/png');
                    // 插入到预览区
                    var progress = 0;
                    function uploading() {
                    }
                };
                var formData = new FormData();
                formData.append('file', e.target.result);
                formData.append('busId', "${pkId}");
                formData.append('fileName', file.name);
                fetch("${ctx}/wechat/eventReport/uploadFile", {
                    method: 'POST',
                    headers: {

                    },
                    body: formData,
                }).then((response) = >response.json()).then((responseData) = >{
                    //console.log(responseData);
                    if (responseData.success) {
                        var imgNames = responseData.data;
                        //这里是将图片上传之后,后台返回的图片的存放路径存到了imgArr数据组//    中,方便前台页面上回显上传的图片。
                        for (var i = 0; i < imgNames.length; i++) {
                            var image = imgNames[i];
                            if (image) {
                                imgArr.push(image);
                            }
                        }
                        //这个就是让图片回显在页面上的函数,每个人的处理方式都不一样,就不贴出来了。
                        refreshImg();
                    } else {
                        layer.msg('上传失败!', {
                            time: 2000
                        });
                    }
                }).
                catch((error) = >{
                    console.error('error', error);
                    layer.msg('上传失败!', {
                        time: 2000
                    });
                });

            };
            reader.readAsDataURL(file);
        }
    });

})

二、后台处理图片

先将base64字符串转为图片。这里使用 restTemplate来请求接口,所以需要将图片文件先转为 FileSystemResource类型,

只能先生成一个 FileSystemResource 类型的文件,上传成功之后在删除即可。

	@RequestMapping(value = "/uploadFile",method = RequestMethod.POST)
	@ResponseBody
    public Map<String,Object> uploadV(HttpServletRequest request,HttpServletResponse response,String file,String fileName,String busId) {
		Map<String,Object> map = new HashMap<String,Object>();
		List<String> resList = new ArrayList<String>();
	    try{
	    	//file = file.substring("data:image/png;base64,".length(),file.length());
	    	file = file.substring(file.indexOf("base64,")+7,file.length());
	    	String tempFileName =  UUID.randomUUID().toString().replaceAll("-", "")+fileName.substring(fileName.lastIndexOf("."));
            //在项目的webapp文件夹下新建一个tempFile文件夹,用来存放生成的临时文件
		    String tempFilePath = request.getSession().getServletContext().getRealPath("/") +"tempFile/" + tempFileName;
		    Base64Utils.Base64ToImage(file, tempFilePath);
		    FileSystemResource resource = new FileSystemResource(tempFilePath);
			MultiValueMap<String, Object> param = new LinkedMultiValueMap<>();
			param.add("file", resource);
			param.add("busId", busId);
            //Constants.fileUploadUrl 是上传图片的接口的url
			String string = restTemplate.postForObject(Constants.fileUploadUrl, param, String.class);
			//System.out.println(string);
			new File(tempFilePath).delete();
			JSONObject json = JSONObject.fromObject(string);
			if(json.getBoolean("success")){
				resList.add(json.getString("data"));
			}
	
	    	map.put("data", resList);
	    	map.put("success", true);
	    } catch(Exception e){
	    	map.put("success", false);
	    	e.printStackTrace();
	    }
	    return map;
	}

将base64字符串转为图片的工具类:

package *****;
import java.io.FileOutputStream;
import java.io.OutputStream;
import org.hibernate.internal.util.StringHelper;
import Decoder.BASE64Decoder;
public class Base64Utils {
	/**
	 * base64字符串转换成图片
	 * @param imgStr		base64字符串
	 * @param imgFilePath	图片存放路径
	 * @return
	 *
	 * @author ZHANGJL
	 * @dateTime 2018-02-23 14:42:17
	 */
	public static boolean Base64ToImage(String imgStr,String imgFilePath) { // 对字节数组字符串进行Base64解码并生成图片
		if (StringHelper.isEmpty(imgStr)) // 图像数据为空
			return false;
		BASE64Decoder decoder = new BASE64Decoder();
		try {
			// Base64解码
			byte[] b = decoder.decodeBuffer(imgStr);
			for (int i = 0; i < b.length; ++i) {
				if (b[i] < 0) {// 调整异常数据
					b[i] += 256;
				}
			}
			OutputStream out = new FileOutputStream(imgFilePath);
			out.write(b);
			out.flush();
			out.close();
			return true;
		} catch (Exception e) {
			return false;
		}
	}
}

三、后台接口处理上传过来的图片

上传文件接口,这里 List<MultipartFile>  files 中就是接收到的文件了,请自行处理,代码省略了。

  @RequestMapping(value = "/hzz/uploadv", method = RequestMethod.POST)
    @ResponseBody
    public Object handleFileUploadV(HttpServletRequest request, HttpServletResponse response) {
        //跨域请求
        response.addHeader("Access-Control-Allow-Origin", "*");//http://localhost:8086
        List<MultipartFile> files = ((MultipartHttpServletRequest) request).getFiles("file");
    }

 

WebMagic 是一款非常好用的 Java 爬虫框架,可以用来爬取各种网站。对于爬取微信公众号,可以使用 WebMagic 结合公众号的历史文章链接来进行爬取。下面是一个简单的爬取微信公众号文章的示例代码: ```java import us.codecraft.webmagic.processor.PageProcessor; import us.codecraft.webmagic.Site; import us.codecraft.webmagic.Spider; import us.codecraft.webmagic.selector.Html; import us.codecraft.webmagic.selector.Selectable; import java.util.List; public class WeChatPublicAccountPageProcessor implements PageProcessor { private Site site = Site.me().setRetryTimes(3).setSleepTime(1000); public Site getSite() { return site; } public void process(Page page) { Html html = page.getHtml(); String title = html.xpath("//title/text()").get(); List<Selectable> articleNodes = html.xpath("//div[@class='weui_media_bd']/h4/a") .nodes(); for (Selectable node : articleNodes) { String articleTitle = node.xpath("/a/text()").get(); String articleUrl = node.xpath("/a/@href").get(); // 把文章链接放到待爬取队列中 page.addTargetRequest(articleUrl); } // 如果是文章页面,则解析文章内容 if (page.getUrl().regex("https://mp.weixin.qq.com/s").match()) { String content = html.xpath("//div[@class='rich_media_content']") .get(); // 把文章内容存储到数据库中或者进行其他处理 // ... } } public static void main(String[] args) { Spider.create(new WeChatPublicAccountPageProcessor()) .addUrl("https://mp.weixin.qq.com/profile?{account_id}") .run(); } } ``` 代码中,我们使用了 WebMagic 的 `PageProcessor` 接口来处理页面,通过 `addUrl()` 方法来添加待爬取的微信公众号链接,然后在 `process()` 方法中解析历史文章链接并添加到待爬取队列中,如果是文章页面,则解析文章内容并进行其他处理。需要注意的是,需要替换花括号中的 `{account_id}` 为对应的公众号ID。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值