不发送HTTP Referer信息加载JavaScript文件

在 Web 开发中,我们经常会遇到跨域请求的问题。跨域的问题,解决方案有很多:代理请求、domain 设置、flash方式、jsonp方式、Access-Control-Allow-Origin。其中,jsonp 的方式最为通用,使用起来也比较简单:通过 JavaScript 回调的方式进行数据跨域传送。

jsonp 方式解决跨域问题XHTML

<script src="http://www.other-domain.cn/api?callback=callback"></script>
在外部接口中(本例 http://www.other-domain.com/api )中,动态输出 Javascript 调用代码,以 PHP 代码为例:

数据接口代码PHP

 代码如下 复制代码
<?php
$data  = 'data';
$callback = isset($_GET['callback']) ? $_GET['callback'] : 'callback';
echo "$callback('$data');";
?>

这样,通过在本地页面中实现 callback 函数即可读取到数据。

JSONP方式获取跨域数据XHTML

 代码如下 复制代码
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Demo</title>
</head>
 
<body>
<script type="text/javascript">
function callback(data){
    alert('获取的数据为: ' + data);
}
</script>
<script type="text/javascript" src="http://www.other-domain.com/api?callback=callback"></script>
</body>
</html>

如果传输的数据比较敏感,不想被未经授权的网站读取,通常的做法是在 api 中做请求的 Referer 校验。如果 Referer 不为空且不是被授权的域名,则拒绝请求。此时,api 的代码类似于:

拒绝来自不受信任网站的请求PHP

 代码如下 复制代码
<?php
if (isset($_SERVER['HTTP_REFERER'])) {
    $url_info = parse_url($_SERVER['HTTP_REFERER']);
    if($url_info['host'] !== 'www.allowed-domain.com') {
        header("HTTP/1.1 404 Not Found");
        exit; 
    }
}
$data  = 'data';
$callback = isset($_GET['callback']) ? $_GET['callback'] : 'callback';
echo "$callback('$data');";
?>

如果没有被授权,这时候调用 api 就会被拒绝。在上面的例子中,相应就是 404。

但是,对于被调用方,这样真的就安全了吗?api 的数据真的不能被未授权网站读取了吗?

答案是:否。

分析上面的 api 接口代码可知,当请求数据时,不发送 HTTP Referer 信息,则可以正常读取数据。

那么,如何加载 JS 而不发送 HTTP Referer 呢?

通常情况下,我们通过 script 标签加载 JS 文件,浏览器都将向 JS 所在服务器发送 Referer 信息:

XHTML

 代码如下 复制代码
GET /api.php?callback=callback HTTP/1.1
Host: www.other-domain.com
Connection: keep-alive
Cache-Control: max-age=0
Accept: */*
Referer: http://www.fising.cn/demo/test.html
Accept-Encoding: gzip,deflate,sdch
Accept-Language: zh-CN,zh;q=0.8,en;q=0.6,ja;q=0.4,zh-TW;q=0.2

但是,通过某种手段,可以使得浏览器加载 JS 文件时,不发送 HTTP Referer。

方法一:HTTPS 页面请求 HTTP JS

当请求页面与被请求资源的 URL Scheme 不同时,不会发送 HTTP Referer。例如,打开淘宝网的登录页面(https://login.taobao.com/member/login.jhtml), 发现其会加载一个来自HTTP服务器的图片资源,这时候就不会发送Referer信息:

HTTP请求头XHTML

 代码如下 复制代码
GET /imgextra/i2/10039155/TB2UQNJapXXXXaXXpXXXXXXXXXX_!!10039155-0-matrixgapp.jpg HTTP/1.1
Host: img02.taobaocdn.com
Connection: keep-alive
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/37.0.2062.120 Safari/537.36
Accept: */*
Accept-Encoding: gzip,deflate,sdch
Accept-Language: zh-CN,zh;q=0.8,en;q=0.6,ja;q=0.4,zh-TW;q=0.2
If-Modified-Since: Thu, 04 Sep 2014 06:33:17 GMT

而这个页面加载的其他来自于 HTTPS 服务器的图片时,则会发送 Referer 信息。

方法二:利用 RFC2397

rfc 2397 定义了一种 URL 格式: data:[<mediatype>][;base64],<data>

有点眼熟不是吗?我们利用base64编码的方式加载图片,正是利用了这点。同样,我们可以利用这个来加载 JS 文件,而不发送 Referer 信息:

利用RFC 2397定义的URL格式发送请求XHTML

 代码如下 复制代码
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Demo</title>
</head>
 
<body>
<iframe src="data:text/html;charset=utf-8,<script type='text/javascript'>function callback(data){alert('获取的数据为: ' + data);}</script><script src='http://www.other-domain.com/api?callback=callback'></script>">
</body>
</html>

可以抓包看看,这个时加载 api 文件,并没有发送 Referer 信息。注意,需要指定 charset ,否则可能会出现乱码问题。

方法三:iframe 标签 src 属性 Hack 法

iframe src hack法XHTML

 代码如下 复制代码
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Demo</title>
</head>
 
<body>
<iframe src="javascript:'<script>function callback(data){alert('获取的数据为: ' + data);}</script><script src='http://www.other-domain.cn/api?callback=callback'></script>'"></iframe>
</body>
</html>

@

时间: 2024-10-24 14:07:10

不发送HTTP Referer信息加载JavaScript文件的相关文章

动态加载JavaScript文件的两种方法_javascript技巧

这篇文章主要为大家详细介绍了动态加载JavaScript文件的两种方法,感兴趣的小伙伴们可以参考一下 第一种便是利用ajax方式,把script文件代码从背景加载到前台,而后对加载到的内容经过eval()实施代码.第二种是,动静创建一个script标签,配置其src属性,经过把script标签插入到页面head来加载js,相当于正在head中写了一个<script src="..."></script>,只可是这个script标签是用js动静创建的 比喻说是我们

LABJS根据需要加载JavaScript文件

LABjs 是一个很小的 JavaScript 工具,用来根据需要加载 JavaScript 文件,通过使用该工具可以提升页面的性能,避免加载不需用到的 JavaScript 文件,可以实现动态并行加载脚本文件,以及管理加载脚本文件的执行顺序. 简单示例 $LAB .script("script1.js", "script2.js", "script3.js") .block(function(){     // wait for all to

异步安全加载javascript文件的方法_javascript技巧

本文实例讲述了异步安全加载javascript文件的方法.分享给大家供大家参考.具体如下: 使用方法: (function() { __safeLoadScript("http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js", function() { alert(jQuery); }); })(); JavaScript实现代码: window.__safeLoadScript = function(src, c

使用RequireJS库加载JavaScript模块的实例教程_javascript类库

js通过script标签的默认加载方式是同步的,即第一个script标签内的js加载完成后,才开始加载第二个,以此类推,直至js文件全部加载完毕.且js的依赖关系必须通过script的顺序才能确保:而在js加载期间,浏览器将停止响应,这大大影响了用户体验,基于此,很多解决js以来和加载的方案出现,require js就是其中之一. requirejs加载的模块,一般为符合AMD标准的模块,即用define定义,用ruturn返回暴露方法.变量的模块:requirejs也可以加载飞AMD标准的模块

LABJS按需动态加载js文件

  为了提高页面的打开和加载速度,我们经常把JS文件放在页面的尾部,但是有些JS必须放在页面前面,这样就会增加页面的加载时间;于是出现了按需动态加载的概念,这个概念就是当页面需要用到这个JS文件或者CSS渲染文件的时候,在去请求这些文件,这样就节省了页面的加载时间 LABjs 是一个很小的 JavaScript 工具,用来根据需要加载 JavaScript 文件,通过使用该工具可以提升页面的性能,避免加载不需用到的 JavaScript 文件,可以实现动态并行加载脚本文件,以及管理加载脚本文件的

详谈LABJS按需动态加载js文件_javascript技巧

LABjs 是一个很小的 JavaScript 工具,用来根据需要加载 JavaScript 文件,通过使用该工具可以提升页面的性能,避免加载不需用到的 JavaScript 文件,可以实现动态并行加载脚本文件,以及管理加载脚本文件的执行顺序. 简单示例 $LAB .script("script1.js", "script2.js", "script3.js") .block(function(){ // wait for all to load

无阻塞加载Javascript的方法和框架

文章简介:用In.js颗粒化管理.加载你的Javascript模块. 近一年来,国内外都十分热衷于异步加载的研究,为了加快页面的载入速度,无阻塞加载Javascript的方法和框架成为了前端开发的焦点和亮点之一. 国外的像基于jQuery的RequireJs,YUI Loader,LabJs,RunJs,国内也有淘宝的SeaJs,豆瓣的DoJs等,这些都是一些十分优秀的模块加载器.但是本文将会向大家介绍一个新的开源的轻量级"多线程"异步模块加载器In.js,In的开发借鉴了Do的一些思

加载 Javascript 最佳实践_javascript技巧

相信很多与页面打过交道的同学都对 Yahoo 的 Best Practices for Speeding Up Your Web Site 不陌生.而这 35 条最佳实践中,对 Javascript 的加载顺序的要求是:Put Scripts at the Bottom.因为根据 HTTP/1.1 specification 看来,在同一时间加载两个文件是最理想的,而 Javascript 脚本会阻碍平行下载.Steve 说那是 2008 – 2009 那个时代用的.现在,加载 Javascri

javascript-Qt加载dll文件后在JavaScript中无法使用

问题描述 Qt加载dll文件后在JavaScript中无法使用 实现目的:在Qt加载dll文件,dl文件实现提示框功能,dll文件的类为Operator,加载后作用js的一个属性被js使用. 问题:在js中就不能成功调用,并提示: Uncaught exception at :/test.js:6: TypeError: Result of expression 'Operator.prompt' [undefined] is not a function. 尝试在main.cpp中调用这个类的