6月16日~29日任务进度及所有工作中遇到的困难

6月16日~29日任务进度及所有工作中遇到的困难

一、 网页前端开发
  • z轴顺序问题
    如果不定义z-index,同级元素按出现先后顺序来决定层级关系,后定义的元素,会层级更高,体现在如果出现在同一位置后出现的会覆盖先出现的。但是如果hover动画中定义元素的移动,在移动过程中元素的层级关系会发生变化,具体怎么变化并不清楚,但是我们可以在hover里定义他的z-index这样就不会出现以上状况。
  • 图片回显
    图片上传回显有两种方式:
    1、上传图片之后存到服务器上,返回一个储存的路径回来就可以了。
    这种方法很简单,但是多了一次和服务交互,不够优雅。
    2、我们利用h5的特性用新增的filereader将input得到的file转成dataurl再将图片显示到页面上。
var fr = new FileReader();
	var myFile = document.getElementById('file');
	fil = myFile.files[0];
	fr.readAsDataURL(fil);
	fr.onload = function (e) {
		$("#hxian").css("display", "block");
		$("#hximg").attr("src", e.target.result);
		$(".fake").css("display", "none");
		$("#tix").css("display", "none");
	}

这里有个小bug,但是如果两次上传的图片一样的话不会触发onload,只要记录一下上次的dataurl就行。

  • 文件拖拽上传
    禁止浏览器打开文件行为
document.addEventListener("drop",function(e){  //拖离   
    e.preventDefault();      
})  
document.addEventListener("dragleave",function(e){  //拖后放   
    e.preventDefault();      
})  
document.addEventListener("dragenter",function(e){  //拖进  
    e.preventDefault();      
})  
document.addEventListener("dragover",function(e){  //拖来拖去    
    e.preventDefault();      
}) 

拖拽,预览文件

var box = document.getElementById('drop_area'); //拖拽区域     
box.addEventListener("drop",function(e){           
    var fileList = e.dataTransfer.files; //获取文件对象    
    //检测是否是拖拽文件到页面的操作            
    if(fileList.length == 0){                
        return false;            
    }             
    //拖拉图片到浏览器,可以实现预览功能    
    //规定视频格式  
    Array.prototype.S=String.fromCharCode(2);  
    Array.prototype.in_array=function(e){  
        var r=new RegExp(this.S+e+this.S);  
        return (r.test(this.S+this.join(this.S)+this.S));  
    };  
    var video_type=["video/mp4","video/ogg"];  
      
    //创建一个url连接,供src属性引用  
    var fileurl = window.URL.createObjectURL(fileList[0]);                
    if(fileList[0].type.indexOf('image') === 0){  //如果是图片  
        var str="<img width='200px' height='200px' src='"+fileurl+"'>";  
        document.getElementById('drop_area').innerHTML=str;                   
    }else if(video_type.in_array(fileList[0].type)){   //如果是规定格式内的视频                    
        var str="<video width='200px' height='200px' controls='controls' src='"+fileurl+"'></video>";  
        document.getElementById('drop_area').innerHTML=str;        
    }else{ //其他格式,输出文件名  
        //alert("不预览");  
        var str="文件名字:"+fileList[0].name;  
        document.getElementById('drop_area').innerHTML=str;      
    }         
    resultfile = fileList[0];             
},false);  
二、chrome插件开发

插件开发的思路,右键点击图片的时候出现菜单,有选项识别图片的选项,识别时直接掉用上面写网页时用的接口,将识别结果复制到粘贴版上。

  • chrome插件开发简单介绍
    manifest.json:这是一个Chrome插件最重要也是必不可少的文件,用来配置所有和插件相关的配置,必须放在根目录。其中,manifest_version、name、version3个是必不可少的,description和icons是推荐的。
    content-scripts:其实就是Chrome插件中向页面注入脚本的一种形式(虽然名为script,其实还可以包括css的),借助content-scripts我们可以实现通过配置的方式轻松向指定页面注入JS和CSS(如果需要动态注入,可以参考下文),最常见的比如:广告屏蔽、页面CSS定制,等等。
    background: 后台(姑且这么翻译吧),是一个常驻的页面,它的生命周期是插件中所有类型页面中最长的,它随着浏览器的打开而打开,随着浏览器的关闭而关闭,所以通常把需要一直运行的、启动就运行的、全局的代码放在background里面。background的权限非常高,几乎可以调用所有的Chrome扩展API(除了devtools),而且它可以无限制跨域,也就是可以跨域访问任何网站而无需要求对方设置CORS。
  • chrome插件开发中遇到的问题
    1.第一阶段,要解决的第一个问题是页面上的图片以file对象的形式发送给服务器。我们只需要获得图片的src,转换成canvas,再转成DataURL,再转成file对象。因为background.js可以随便跨域所以很轻松就传输上去了,但是这样子转换因为background.js是独立于原页面的,所以转换过程中相当于又向这个网页的服务器请求了一次图片,所以导致上传到服务器的图片和页面上的图片不一样。
	var img = document.querySelector(img);
	var canvas = document.createElement("canvas");
	canvas.width = img.width;
	canvas.height = img.height;
	var ctx = canvas.getContext("2d");
	ctx.drawImage(img, 0, 0, img.width, img.height);
	var url = canvas.toDataURL('image/png');
	var arr = url.split(','),
		mime = arr[0].match(/:(.*?);/)[1],
		bstr = atob(arr[1]),
		n = bstr.length,
		u8arr = new Uint8Array(n);
	while (n--) {
		u8arr[n] = bstr.charCodeAt(n);
	}
	var filename = "yzm.png";
	var fil = new File([u8arr], filename, {
		type: mime
	});
	var formData = new FormData();
	formData.append("img", fil);

2.第二阶段,解决上传图片跟页面图片不一致的问题,通过同学了解到油猴插件,我放弃原生的方式开发插件,在油猴插件的基础上开发这个插件,油猴插件开发很简单,就只需要写一个js,并在js的开始按照油猴的标准写下注释就行,另外油猴还提供了很多很好用的自己带函数。在用油猴插件开发完成后,我发现页面上的图片转成dataurl之后在生成img和页面上的图片是一样的,但是又出现了另外一个bug就是无法发送ajax请求,如果在油猴里用ajax发送请求可能会出现跨域问题,所以我们可以使用油猴自己的http请求的函数,这样可以解决跨域问题,但是我出现的并不是跨域问题,而是在跨域请求之前的一个错误,不能从一个https页面的里发送一个http的请求,错误如图:
在这里插入图片描述
很神奇的是油猴也可以解决这个错误,成功的发送请求,但是在服务器端却无法响应请求,因为服务器处理不了https的请求,而我猜测那个自带的函数就是把http请求转成https请求所以才可以逃过服务器的安全机制。但是经过油猴的启发,我觉得可能是因为油猴是嵌入到页面的js所以可以把页面上的img转成dataurl之后还跟页面上一样的,因为油猴是嵌入的所以应该和页面都共享缓存,而转换的时候并不需要再次请求图片,而是直接从缓存中拿到图片就可以了。
3.第三阶段,我又从油猴开发换到了原生开发,在content-script上把img转成dataurl,然后再通过通信机制把dataurl传给background,再由background发送ajax请求,background.js发送ajax请求没有任何跨域问题所以我们就由它来发送,但是这里又出现一个问题在这里插入图片描述就是chrome个个js之间通讯通道,存在的时间太短了,如果再里面放一个执行很长时间的函数,就会报上面的错。不过我们可以提前声明一个全局的Image变量让他load一下就行,这样就会触发onload函数,这个函数的执行实现不算在通道里面。以上就可以大致完成验证码识别的chrome插件了。

//background.js
chrome.runtime.onInstalled.addListener(createContextMenu);
chrome.runtime.onStartup.addListener(createContextMenu);

function createContextMenu() {
	chrome.contextMenus.removeAll(function() {
		chrome.contextMenus.create({
			id: 'plan1',
			title: '通道一识别',
			contexts : ['image'],
		});
		chrome.contextMenus.create({
			id: 'plan2',
			title: '通道二识别',
			contexts: ['image'],
		});
	});
}

var url;
var ans;
chrome.contextMenus.onClicked.addListener(function(info, tab) {
	sendMessageToContentScript("验证码图片已经上传,正在识别!", function(response)
	{
		console.log('来自content的回复:'+response);
	});
	var arr = url.split(','),
		mime = arr[0].match(/:(.*?);/)[1],
		bstr = atob(arr[1]),
		n = bstr.length,
		u8arr = new Uint8Array(n);
	while (n--) {
		u8arr[n] = bstr.charCodeAt(n);
	}
	var filename = "yzm.png";
	var fil = new File([u8arr], filename, {
		type: mime
	});
	var formData = new FormData();
	formData.append("img", fil);
	$.ajax({
		url: "http://xxx.xxxx.xxxx:xxxx/imgProcess/upload",
		type: "post",
		data: formData,
		dataType: "json",
		cache: false,
		processData: false,
		contentType: false,
		success: function(data) {
			if (data.code == 200) {
				if(info.menuItemId=='plan2')
					ans = data.imgCode2;
				else
					ans = data.imgCode1;
				sendMessageToContentScript("识别成功,结果为:"+ans+",可以粘贴!", function(response)
				{
					console.log('来自content的回复:'+response);
				});
				const input = document.createElement('input');
				document.body.appendChild(input);
				input.setAttribute('value', ans);
				input.select();
				if (document.execCommand('copy')) {
					document.execCommand('copy');
					console.log('复制成功');
				}
				document.body.removeChild(input);
			} else
				alert("分析失败!");
		},
		error: function(err) {
			alert("请求失败!")
		}
	});
});

chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) {
	url = request;
	sendResponse("我已收到!");
});
function sendMessageToContentScript(message, callback)
{
	chrome.tabs.query({active: true, currentWindow: true}, function(tabs)
	{
		chrome.tabs.sendMessage(tabs[0].id, message, function(response)
		{
			if(callback) callback(response);
		});
	});
}
var Tip;
window.onload=function() {
	Tip=AddTip();
	$("img").each(function() {
		$(this).on("contextmenu", function() {
			var that=$(this);
			var img = Aimed(that);
			IdentifyResult = ConversionBase(img);
		});
	})
}
function Climb(Element, ElementLocalName, Joint = '') {
	// console.log('上次过来值' + Joint);
	var ElementType = (Element.id ? Element.id : Element.className ? Element.className.replace(/\s/g, ".") : false);
	var Symbol = (Element.id ? "#" : Element.className ? "." : false);
	if (ElementType && ElementLocalName == Element.localName) {
		var Address = ElementLocalName + Symbol + ElementType;
	} else {
		var Address = Symbol + ElementType + ' ' + ElementLocalName;
	}
	// console.log('我叫' + Address);
	// console.log('叫这个名字的有' + $(Address).length);
	if ($(Address).length == 1) {
		// console.log('只有一个' + Address);
		// console.log('最后一次拼接' + Address + ' ' + Joint);
		return Address + ' ' + Joint;
		//我的名字唯一
	} else {
		// console.log(Element);
		// console.log('这是我的父辈' + $(Element).parent()[0].className);
		//让我的父辈去一辈一辈问我的老祖宗是谁
		var Joint = this.Climb($(Element).parent()[0], $(Element).parent()[0].localName, Address + ' ' + Joint)
		return Joint;
	}
}

function ConversionBase(img) {
	var img = document.querySelector(img);
	var canvas = document.createElement("canvas");
	canvas.width = img.width;
	canvas.height = img.height;
	var ctx = canvas.getContext("2d");
	ctx.drawImage(img, 0, 0, img.width, img.height);
	var url = canvas.toDataURL('image/png');
	chrome.runtime.sendMessage(url, function(response) {
		console.log(response);
	});
}

function Aimed(Element) {
	Element = Element[0];
	var ElementLocalName = Element.localName;
	var Symbol = (Element.id ? "#" : Element.className ? "." : false);
	if (!Symbol) {
		return Climb(Element.parentNode, ElementLocalName);
	} else {
		return Climb(Element, ElementLocalName);
	}
}
function AddTip() {
    var TipHtml = $("<div></div>").text("Text.");
    TipHtml.css({
      "background-color": "rgba(211,211,211,0.86)",
      "display": "flex",
      "align-items": "center",
      "justify-content": "center",
      "position": "fixed",
      "color": "black",
      "top": "-2em",
      "height": "2em",
      "margin": "0em",
      "padding": "0em",
      "font-size": "1.2em",
      "width": "100%",
      "text-align": "center",
      "z-index": "999",
    })
    $("body").prepend(TipHtml);
    return TipHtml;
}

function Hint(Content, Duration) {
    Tip.stop(true, false).animate({
      top: '-2em'
    }, 300, function() {
      Tip.text(Content);
    });
    Tip.animate({
      top: '0em'
    }, 500).animate({
      top: '0em'
    }, Duration ? Duration : 3000).animate({
      top: '-2em'
    }, 500)
    return;
}
var timg=new Image;
var cht;
chrome.runtime.onMessage.addListener(function(request, sender, sendResponse)
{
	cht=request;
	console.log(cht);
	timg.src="https://www.baidu.com/img/flexible/logo/pc/result@2.png";
	sendResponse('我收到了你的消息!');
});
timg.onload=function(){
	Hint(cht,1500);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值