所以我写了一个Video.js插件,报告回谷歌分析和我们的自定义报告。
我们发送回页面的每个JSONP请求都使用this method使用encodeURIComponent进行编码。前几个正确发射。然后,TypeError: '[object Object]' is not a function (evaluating 'encodeURIComponent(p)')
开始出错。这只发生在Safari中。 (我正在使用OSX Mavericks上的safari 7.0.1)
我甚至尝试使用encodeURI
来完成整个网址字符串,但该功能也会发生同样的事情。
我创建了一个[JS FIDDLE] [2]来演示这个问题。我用一些示例代码重新创建它是不成功的,所以我在外部资源中包含了所有相关文件。如果它没有这样做,请重新运行它发生的页面大约85%的时间。
我首先将事件添加到跟踪
this.on('play',onPlay);
this.on('pause',onPause);
当事件触发时,它会被这些函数捕获
function onPlay( e ) {
videoData = getVideoData();
doTracking({
'category': videoData.cid,
'action': videoData.vid,
'label': 'Play',
'value': null
});
}
function onPause( e ) {
videoData = getVideoData();
doTracking({
'category': videoData.cid,
'action': videoData.vid,
'label': 'Pause',
'value': getTime()
});
}
从
获取视频数据function getVideoData() {
var src = videojsRef.player().currentSrc();
var srcSplit = src.split('/');
var filename = srcSplit[srcSplit.length-1];
var filenameSplit = filename.split('.');
var cid = filenameSplit[0];
var vid = filenameSplit[1];
var type = filenameSplit[2];
var returnObj = {
'cid': cid,
'vid': vid,
'filename': filename
};
return returnObj;
}
然后调用“doTracking”,它只是一个调用两种跟踪功能的辅助函数。
function doTracking( opt ) {
if ( gaType && bvReady ) { // Are both tracking types initialized
// Send to google
googleTrack( opt );
// Send to BetterVideo
bvTrack( opt );
} else {
queue.push( opt );
}
}
哪个叫bvTrack(opt)
function bvTrack( opt ) {
var args = {
pid: playerid,
cid: opt.category,
vcd: opt.action,
a: opt.label,
callback: '{callback}'
};
if ( opt.value !== null ) {
args.val = opt.value;
}
// Heres where the trouble starts
new videojs.JSONP('http://jsfiddle.net/echo/jsonp/?'+serializeToQuery(args), function( response ) {
console.log('[BV Reporting] Tracking Response: ', arguments );
})
}
数据在此处序列化
function serializeToQuery( obj ) {
var str = [];
console.log( "serializeToQuery", obj );
for(var p in obj) {
if ( obj.hasOwnProperty(p) ) {
console.log( ' property', p, obj[p]);
console.log( ' encodeURIComponent', typeof encodeURIComponent == 'function' ? 'function' : encodeURIComponent );
console.log( ' encoded property', encodeURIComponent(p) + "=" + encodeURIComponent(obj[p]));
str.push(encodeURIComponent(p) + "=" + encodeURIComponent(obj[p]));
}
}
return str.join("&");
}
然后传递给d3.js inspired JSONP(我相信我在这里找到了
videojs.JSONP = function (url, callback) {
var docHead = document.getElementsByTagName('head')[0];
function rand() {
var chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz',
c = '', i = -1;
while (++i < 15) c += chars.charAt(Math.floor(Math.random() * 52));
return c;
}
function create(url) {
var e = url.match(/callback=jsonp.(\w+)/),
c = e ? e[1] : rand();
videojs.JSONP[c] = function(data) {
callback(data);
delete videojs.JSONP[c];
docHead.removeChild(script);
};
return 'videojs.JSONP.' + c;
}
var cb = create(url),
script = document.createElement('script');
script.type = 'text/javascript';
script.src = url.replace(/(\{|%7B)callback(\}|%7D)/, cb);
docHead.appendChild(script)
};
serializeToQuery Object {
a: "Pause"
callback: "{callback}"
cid: "oceans"
pid: "885FA551-A873-4BB9-891A-ABC08CD47D36"
val: 6
vcd: "mp4"
}
property pid 885FA551-A873-4BB9-891A-ABC08CD47D36
encodeURIComponent function
encoded property pid=885FA551-A873-4BB9-891A-ABC08CD47D36
property cid oceans
encodeURIComponent function
encoded property cid=oceans
property vcd mp4
encodeURIComponent function
encoded property vcd=mp4
property a Pause
encodeURIComponent function
encoded property a=Pause
property callback {callback}
encodeURIComponent function
encoded property callback=%7Bcallback%7D
property val 6
encodeURIComponent function
encoded property val=6
但是在2或3次JSONP调用之后,它会输出:
serializeToQuery Object {
a: "Play"
callback: "{callback}"
cid: "oceans"
pid: "885FA551-A873-4BB9-891A-ABC08CD47D36"
vcd: "mp4"
}
property pid 885FA551-A873-4BB9-891A-ABC08CD47D36
encodeURIComponent Object {
cid: "oceans"
filename: "oceans.mp4"
vid: "mp4"
}
[Error] TypeError: '[object Object]' is not a function (evaluating 'encodeURIComponent(p)')
serializeToQuery (videojs.bvReporting.js, line 531)
bvTrack (videojs.bvReporting.js, line 481)
doTracking (videojs.bvReporting.js, line 329)
onPlay (videojs.bvReporting.js, line 113)
ret (video.dev.js, line 769)
dispatcher (video.dev.js, line 295)
trigger (video.dev.js, line 529)
trigger (video.dev.js, line 1868)
eventHandler (video.dev.js, line 5376)
ret (video.dev.js, line 769)
dispatcher (video.dev.js, line 295)
正如您所看到的,encodeURIComponent
现在是调用它的最后一个对象。
有什么想法吗?
答案 0 :(得分:0)
在每个跟踪事件监听器中,videoData = getVideoData()
将var
添加到问题停止后videoData
。有谁知道为什么这可能是原因?我知道它被设置为全局变量但是encodeURIComponent如何设置为对象?