获取游戏链接
小游戏是通过iframe嵌入到页面中的,之前抓取iframe的链接,直接在新标签页打开,是能看到一个纯纯的小游戏,但现在策略改了,直接打开iframe中小游戏的链接,会提示“请从4399域名访问”
观察该url的网络请求,会有一个Referer,也正是因为这个Referer才导致不能从其他页面引用该小游戏的iframe链接
要想在localhost的测试地址成正确嵌入iframe而不报错,也验证是不是因为Referer的原因,可以把本地host做一个映射:
127.0.0.1 www.4399.com
结果能正确访问,也验证了确实限制了Referer,但不可能把自己的域名配置成4399.com,所以还是要想办法绕过限制
绕过Referer的限制
- 前端处理:前端没有办法仿造referer
- 后端转发:在后端就可以通过http请求拿到链接内容时,指定referer ```javascript import axios from ‘axios’; import { getUrlParam } from ‘../helpers/utils’;
export default async function (req, res) { res.setHeader(‘Content-Type’, ‘text/html; charset=utf-8’); const param = getUrlParam(req.url); const url = param && param.url; const config = { headers: { Referer: ‘http://www.4399.com‘ } }; const data = await axios.get(decodeURIComponent(url), config); res.end(data); }
调用:```javascript<iframeframeborder="0"scrolling="no"allowfullscreen="allowfullscreen"referrerpolicy="same-origin":src="`/tapi/xyx/iframe?url=${encodeURIComponent(http://sda.4399.com/4399swf/upload_swf/ftp24/gamehwq/20180316/15b/index.htm)}`"class="url_container"style="width: 714px; height: 535px;"/>
处理静态资源访问
通过后端代理以后,代码中想多路径都变成相对于/tapi/xyx/iframe的路径了,这显然不是我们想要的,应该是相对于小游戏部署的路径,这里就是http://sda.4399.com/4399swf/upload_swf/ftp24/gamehwq/20180316/15b 。解决这个问题可以通过设置base,将base标签插入到代码head中:
const data = await axios.get(decodeURIComponent(url), config);const str = data.data.replace('<head>', '<head><base href="http://sda.4399.com/4399swf/upload_swf/ftp24/gamehwq/20180316/15b/" />');res.end(str);
这样相对路径的静态资源就能访问到了了。
document.location.href处理
代码中有使用document.location.href的地方,因为做了转发,所以这个值也变了,所以对返回结果中出现这个值的地方做硬编码替换
const data = await axios.get(decodeURIComponent(url), config);const str = data.data.replace('<head>', '<head><base href="http://sda.4399.com/4399swf/upload_swf/ftp24/gamehwq/20180316/15b/" />').replace('document.location.href', '\'http://sda.4399.com/4399swf/upload_swf/ftp24/gamehwq/20180316/15b/index.htm\'');res.end(str);
JS引入的动态生成
返回的html中,JS文件的引入不是直接写的script标签,而是通过createElement生成的,这样生成的代码就不允许JS跨域了,否则浏览器会报CROS错误
(function (document, url, fgJS, firstJS) {fgJS = document.createElement('script');firstJS = document.getElementsByTagName('script')[0];fgJS.src = url + encodeURIComponent(document.location.href);firstJS.parentNode.insertBefore(fgJS, firstJS);})(document, './gameapi/v1.js?e=');
遇到跨域问题,基本上就无解了,gameapi/v1.js里面的js引用依然是通过createElement生成的
结论
外部网站直接嵌入小游戏不可行
