事情是這樣的,今天上午下班前,朋友發我一個js文件,說視頻不播放,核心代碼大概是這樣子的:
var player = document.createElement('video'); var source = document.createElement('source'); player['id'] = 'videoplayer'; player['class'] = 'video-js vjs-default-skin '; player['controls'] = ' '; player['poster'] = vPng; player['preload'] = 'auto'; player['data-setup'] = '{"fluid": true}'; player['muted'] = 'true'; player['autoplay'] = 'true'; source['type'] = 'video/mp4'; source['src'] = vUrl; document.body.appendChild(player); document.getElementById("videoplayer").appendChild(source);
朋友說,在瀏覽器上播放正常,但是在android瀏覽器,app的webview里也不正常。
我這邊看了一下,也是只有一個封面而已,mp4文件響應200,返回100K以內的數據,response headers里面的Connection:Close。
我是誰,Copying and Pasting from Internet 技能點滿了的人,
於是,發動了我的技能:
第一個看到了吧,google的devtool 結合Chrome使用,但是這貨色iMac結合Chrome的,所以用Google的這個不大合適,
然后薦了我之前用過的weinre。
與好奇心和責任心無關,本着八卦與無聊的精神,我追着問結果,
追問結果到下午,好友上線告訴我結果:webview沒有報錯,代碼也正常,就是不報錯。
這時候,我無意之中刷新了一下頁面,我了個擦,居然有了。
怎么回事?莫非是緩存問題?
clear browser cache, clear cookie, restart nodejs server。(用的nodejs做的靜態文件服務器,file:的話會有一些其他的問題)
問題又粗線了:只有一個封面,毛都播放不了。
直接訪問mp4文件,播放正常。
這尼瑪是不是一個跨域問題啊?
於是將跨域的資源統統下載到我的Nodejs靜態服務器,
將video的src路徑改為本地服務器的相對路徑,
Bingo!
一切正常得不能再正常了。
至此,
可以確定是一個跨域所導致的加載問題,
給video添加crossOrigin = '*';
沒啥卵用。
response headers里面Access Allow Origin根本就沒有,
於是跟朋友講需要去資源服務器里面加一下配置。
但是,
這個不是他們公司的維護范圍;
叫他下載到他們的服務器里面去,
馬蛋,不鳥我。
於是,
我又發揮了我的第二個滿點技能,
走偏門。
有什么元素可以繞過跨域限制的呢?
似乎有個iframe可以用。
科科。
於是在上面那段代碼前面加上:
var iframe = document.createElement('iframe'); iframe['src'] = vUrl; iframe['width'] = 580; iframe['height'] = 434; document.body.appendChild(iframe); return;
搞定,跨你妹個蛋的域哇。
咩哈哈!!!
雖然問題看起來是解決了,
但是我告訴他最終解決方案不是這個,
因為你這么嵌入頁面的話是非常危險的。
同時也不推薦大家去隨便嵌入別人的網頁到自己的應用中,
因為很危險哪。
正式的解決方案還是要靠去資源服務器添加跨域訪問限制的配置。
最后是一張正常訪問和不正常訪問的請求響應的對比圖:
很充實有趣有記錄意義的一次bug解決體驗。