目标网站:http://www.how-old.net/
网站功能:上传照片,服务器返回数据、显示照片中人物性别与年龄。
简介:通过流程梳理,网站通过Ajax将用户上传图片或是在线图片以post形式传到服务器,服务器分析图片,并调用自身分析系统,返回Json数据,客户端Js根据json数据生成样式文件,显示出示照片中人物性别与年龄。
应用流程
实例分析,进入网站后,可以通过两种方式向服务器传送图片,1、use this photo,向服务器发送在线图片,2、use your own phonto 上传个人图片发送至服务器
(1)use this photo,向服务器发送在线图片,点击按钮,触发analyzeUrl()事件,所在js文件http://www.how-old.net/bundles/demo
function analyzeUrl() {
var n = document.getElementById("SelectorBox").getBoundingClientRect(),
t = document.elementFromPoint(n.left + n.width / 2, n.top + n.height / 2),
r = $(t).attr("data-url"),
u = $(t).attr("data-orig-domain"),
f = $(t).attr("data-orig-url"),
i = $(t).attr("data-image-name");
i == undefined && (i = null);
updateThumbnail(r, u, f);
processRequest(!1, r, i)
}
function processRequest(n, t, i, r, u) {
window.location.hash = "results";
deleteFaceRects();
$("#attributionMainId").hide();
$("#jsonEventDiv").hide();
var h = $("#analyzingText").val() + '<span><img id="loadingImage" src="/Images/ajax-loader_1.gif" /><\/span>',
e = $("#couldntDetectText").val() + " " + $("#VerifyImageText").val(),
c = $("#couldntDetectText").val();
$("#analyzingLabel").css("visibility", "visible");
$("#improvingLabel").css("visibility", "hidden");
$("#analyzingLabel").html(h);
var o = {},
s = !1,
f = "/Home/Analyze",
l = $("#uploadBtn").get(0).files,
a = $("#isTest").val(),
v = $("#source").val(),
y = $("#siteVersion").val();
if (f += "?isTest=" + a + "&source=" + v + "&version=" + y, n) {
if (r != null && r > 3145728) {
$("#jsonEventDiv").hide();
$("#analyzingLabel").html(e);
$("#analyzingLabel").css("visibility", "visible");
return
}
o = l[0];
s = "application/octet-stream"
} else f += "&faceUrl=" + encodeURIComponent(t) + "&faceName=" + i;
$.ajax({
type: "POST",
url: f,
contentType: s,
processData: !1,
data: o,
success: function(n) {
var t = JSON.parse(n);
t == null || t.Faces == null || t.Faces.length === 0 ? ($("#analyzingLabel").html(c), $("#analyzingLabel").css("visibility", "visible")) : (renderImageFaces(t.Faces, u), $("#analyzingLabel").css("visibility", "hidden"));
$("#improvingLabel").css("visibility", "visible");
t != null && (showViewSourceLink(), $("#jsonEvent").text(t.AnalyticsEvent));
adjustAttirbutionLinkLocation()
},
error: function() {
$("#jsonEventDiv").hide();
$("#analyzingLabel").html(e);
$("#analyzingLabel").css("visibility", "visible");
adjustAttirbutionLinkLocation()
}
})
}
window.location.hash = "results";并没有重新加载页面,
主体部分就是ajax的数据发送,与返回数据的处理,
发送部分,
url:f----/Home/Analyze(API)+&faceurl="&faceUrl=" + encodeURIComponent(t) (图片路径)
type:post
data: o,在线图片不起作用,上传本地图片时,传送图片文件,
返回处理部分
var t = JSON.parse(n);将返回json数据,转成对象
该部分谷歌浏览器Network数据监测
数据请求
数据请求
Remote Address:191.236.156.64:80
Request URL:http://www.how-old.net/Home/Analyze?isTest=False&source=&version=001&faceUrl=Images%2Ffaces2%2Fmain0012.jpg&faceName=faces2/main0012.jpg
Request Method:POST
Status Code:200 OK
数据返回
返回数据:"{\"AnalyticsEvent\":\"[\\r\\n {\\r\\n \\\"face\\\": {\\r\\n \\\"age\\\": 24.0,\\r\\n \\\"gender\\\": \\\"Male\\\"\\r\\n },\\r\\n \\\"event_datetime\\\": \\\"2015-07-27T16:07:19.3746962Z\\\",\\r\\n \\\"user_id\\\": \\\"D16ADBB2-E5E3-4E7B-ADF6-3291227F535B\\\",\\r\\n \\\"session_id\\\": \\\"408c626c-5b8b-468a-86a4-4195e491d1f6\\\",\\r\\n \\\"submission_method\\\": \\\"FaceList\\\",\\r\\n \\\"user_agent\\\": \\\"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.118 Safari/537.36\\\",\\r\\n \\\"location\\\": {\\r\\n \\\"latitude\\\": 36.66,\\r\\n \\\"longitude\\\": 117.13\\r\\n },\\r\\n \\\"location_city\\\": {\\r\\n \\\"latitude\\\": 36.7,\\r\\n \\\"longitude\\\": 117.1\\r\\n },\\r\\n \\\"is_mobile_device\\\": false,\\r\\n \\\"browser_type\\\": \\\"Chrome\\\",\\r\\n \\\"platform\\\": \\\"MacOSX\\\",\\r\\n \\\"mobile_device_model\\\": \\\"Unknown\\\"\\r\\n }\\r\\n]\",\"Faces\":[{\"faceId\":null,\"faceRectangle\":{\"top\":182,\"left\":205,\"width\":226,\"height\":226},\"attributes\":{\"gender\":\"Male\",\"age\":24.0}}]}"
renderImageFaces(t.Faces, u),将json数据显示出样式来。
function renderImageFaces(n, t) {
current_faces = n;
updateOrigImageDimensions(drawFaceRects, t)
}
function drawFaceRects() {
var n;
if ($("#faces").html("<div><\/div>"), n = $("#thumbnail"), current_faces != null) {
var r = $("#thumbContainer"),
u = n.offset().left - r.offset().left,
t = n.height() / image_orig_height,
i = n.width() / image_orig_width,
f = current_faces.length;
$.each(current_faces,
function(r, e) {
var s = e.faceRectangle,
l = e.attributes.age,
a = e.attributes.gender,
o = {},
h, c;
o.top = Math.round(t * s.top);
o.height = Math.round(t * s.height);
o.left = Math.round(i * s.left) + u;
o.width = Math.round(i * s.width);
h = adjustRectOrientation(o, n.width(), n.height(), image_orig_rotation);
c = $("#faces”);
add_rect = function(n, t, i, r, u, f) {
var o = "rect" + Math.round(Math.random() * 1e4),
e = null,
c = "n/a",
s, h, l, a;
t != null && (c = Math.round(Number(t)));
s = static_url+"/Images/icon-gender-male.png";
i != null && i.toLowerCase() === "female" && (s = static_url+"/Images/icon-gender-female.png");
h = f <= 2 ? "big-face-tooltip" : "small-face-tooltip";
e = '<div><span><img src="' + s + '" class=' + h + "><\/span>" + c + "<\/div>";
$(e).css("background-color", "#F1D100");
l = '<div data-html="true" class="child face-tooltip ' + h + ' " id="' + o + '"/>';
$(l).appendTo(u).css("left", n.left + "px").css("top", n.top + "px").css("width", n.width + "px").css("height", n.height + "px").css("border", "1px solid white").css("position", "absolute");
e != null && (a = "top", $("#" + o).tooltip({
trigger: "manual",
show: !0,
placement: a,
title: e,
html: !0
}), $("#" + o).tooltip("show"))
};
代码追踪流程:renderImageFaces=》drawFaceRects=》add_rect
最后add_rect函数中 l用于定位脸部位置,e用于显示性别、年龄参数,/Images/icon-gender-female.png为性别图片,注意tooltip()调用的是bootstrap的方法,要引入bootstrap.js文件
示例
:
(2)use your own phonto,
上传个人图片
点击按钮,触发#uploadBtn的点击事件
$(window).load(function() {
document.getElementById("uploadBtn").addEventListener("change", handleFileSelect, !1);
document.getElementById("uploadBtn").addEventListener("click",
function() {
this.value = null
},
!1);
window.location.hash = "";
iOS = navigator.userAgent.match(/(iPad|iPhone|iPod)/g) ? !0 : !1
});
jQuery 将”uploadBtn" 的触发事件绑定了handleFileSelect函数
感谢老朋友徐在过程中的帮助。