LocalStorage在Chrome里的实现
前段时间我们在实现CanTK-Runtime时,也曾在V8基础上模拟过浏览器的LocaleStorage功能,其实现非常简单:每个domain的数据使用的单独文件存储,因为同一时间只有一个游戏运行,所以文件操作只是放到了后台线程执行。但是Chrome里的实现就非常复杂了,它主要包括四部分:
- 0.根据IDL文件产生出来的代码,称为Binding代码(gen/blink/bindings/modules/v8/V8Storage.cpp)。这些代码是JS与C++之间的桥梁,JS调用C++时传递过来的参数是一个数组,它负责把参数拆解出来然后调用实际的函数,执行完成后把参数返回给JS。
static void setItemMethod(const v8::FunctionCallbackInfo<v8::Value>& info)
{
ExceptionState exceptionState(ExceptionState::ExecutionContext, "setItem", "Storage", info.Holder(), info.GetIsolate());
if (UNLIKELY(info.Length() < 2)) {
setMinimumArityTypeError(exceptionState, 2, info.Length());
exceptionState.throwIfNeeded();
return;
}
Storage* impl = V8Storage::toImpl(info.Holder());
V8StringResource<> key;
V8StringResource<> data;
{
key = info[0];
if (!key.prepare())
return;
data = info[1];
if (!data.prepare())
return;
}
impl->setItem(key, data, exceptionState);
if (exceptionState.hadException()) {
exceptionState.throwIfNeeded();
return;
}
}
- 1.与浏览器JS对接的模块(WebKit/Source/modules/storage)。Binding代码会调用到这里来,这里主要做些参数以及安全方面的检查,然后调用WebStorageArea的接口。
void StorageArea::setItem(const String& key, const String& value, ExceptionState& exceptionState, LocalFrame* frame)
{
if (!canAccessStorage(frame)) {
exceptionState.throwSecurityError("access is denied for this document.");
return;
}
WebStorageArea::Result result = WebStorageArea::ResultOK;
m_storageArea->setItem(key, value, frame->document()->url(), result);
if (result != WebStorageArea::ResultOK)
exceptionState.throwDOMException(QuotaExceededError, "Setting the value of '" + key + "' exceeded the quota.");
}
- 2.客户端代理(content/renderer/dom_storage/webstoragearea_impl.cc)。上面需要的WebStorageArea接口的实现是WebStorageAreaImpl在chrome里实现的(在WebKit之外)。让我有些惊讶的是,这些代码居然是放在renderer目录下的。后来想了一下,Storage与renderer没关系,但是这些代码是在render进程程执行的。每个标签都有一个Render进程,多个标签可能是同一个domain,也就是会存取同一个Storage,出于性能和共享考虑,所以把真正执行文件系统(数据库)的操作放在服务进程里了,这个模块是客户端的代理。
void WebStorageAreaImpl::setItem(
const WebString& key, const WebString& value, const WebURL& page_url,
WebStorageArea::Result& result) {
if (!cached_area_->SetItem(connection_id_, key, value, page_url))
result = ResultBlockedByQuota;
else
result = ResultOK;
}
bool DOMStorageCachedArea::SetItem(int connection_id,
const base::string16& key,
const base::string16& value,
const GURL& page_url) {
// A quick check to reject obviously overbudget items to avoid
// the priming the cache.
if (key.length() + value.length() > kPerStorageAreaQuota)
return false;
PrimeIfNeeded(connection_id);
base::NullableString16 unused;
if (!map_->SetItem(key, value, &unused))
return false;
// Ignore mutations to 'key' until OnSetItemComplete.
ignore_key_mutations_[key]++;
proxy_->SetItem(
connection_id, key, value, page_url,
base::Bind(&DOMStorageCachedArea::OnSetItemComplete,
weak_factory_.GetWeakPtr(), key));
return true;
}
- 3.服务器及数据库(content/browser/dom_storage/dom_storage_area.cc)。这个是在浏览器的主进程里执行的,数据库使用的Sqlite。
bool DOMStorageArea::SetItem(const base::string16& key,
const base::string16& value,
base::NullableString16* old_value) {
if (is_shutdown_)
return false;
InitialImportIfNeeded();
if (!map_->HasOneRef())
map_ = map_->DeepCopy();
bool success = map_->SetItem(key, value, old_value);
if (success && backing_ &&
(old_value->is_null() || old_value->string() != value)) {
CommitBatch* commit_batch = CreateCommitBatchIfNeeded();
commit_batch->changed_values[key] = base::NullableString16(value, false);
}
return success;
}
LocalStorage在Chrome里的实现的更多相关文章
- requestAnimationFrame在Chrome里的实现
requestAnimationFrame是HTML5游戏和动画必不可少的函数,相对于setTimeout或setInterval它有两个优势,一是它注册的回调函数与浏览器的渲染同步,不用担心Time ...
- 【27前端】base标签带有href属性会让chrome里的svg元素url失效
一个chrome的问题,但具体原因不明. 触发条件:chrome浏览器base标签里href属性有值的时候 触发问题:svg里面的元素如果有用url的滤镜和模糊,则会失效,在firefox里和IE10 ...
- 玩爽了!直接在Chrome里抓取数据
一个小测试发现可以自动做题,于是想通过脚本的方式看能不能获取相应的题库,刚好可以学习一下JS异步操作.花了一天时间,总算跑顺利了,遇到了不少坑.记录下来分享. 1.JS如何顺序执行 JS有强大的异步操 ...
- 直接在Chrome里抓取数据
一个小测试发现可以自动做题,于是想通过脚本的方式看能不能获取相应的题库,刚好可以学习一下JS异步操作.花了一天时间,总算跑顺利了,遇到了不少坑.记录下来分享. 1.JS如何顺序执行 JS有强大的异步操 ...
- favicon.ico在chrome里显示正常,在ie,edge浏览器中不显示
代码: <head> <meta charset="UTF-8"> <link href="imgs/favicon.ico" r ...
- 关闭在chrome里使用双指前进后退页面的功能
defaults write com.google.Chrome AppleEnableSwipeNavigateWithScrolls -bool FALSE
- 在CHROME里安装 VIMIUM 插件, 方便操作
VIMIUM 插件使用方法 VIMIUM 命令列表 网页导航 j, :向下滚动网页 k, :向上滚动网页 h : 向左滚动 l : 向右滚动 gg : 滚动到网页头部 G : 滚动到网页底部 :向上翻 ...
- 如何在CHROME里调试前端代码?
以前看前端们调得很神的, 刚看书到这里,作一个记录,演练了一下,确实有点神!!! :) <!DOCTYPE html> <html lang="en"> & ...
- Chrome 里的请求报错 "CAUTION: Provisional headers are shown" 是什么意思?
在调试器中看到文件显示提示为 CAUTION: Provisional headers are shown, 可是直接复制链接访问资源却可以正常访问, 最后发现是https 问题,资源采用ssl协议, ...
随机推荐
- JavaScript的构造器与对象(二)
constructor 的用法:对象的构造函数 每一个函数的Prototype属性指向的对象都包含唯一一个不可枚举属性constructor,该属性的值是这么一个对象:它指向了它所在的构造函数. 语 ...
- Http 请求
public static string HttpGet(string url) { HttpWebRequest request = (HttpWebRequest)WebRequest.Creat ...
- windows api线程
一.1.定义入口函数static void threadFunc(void);//在TestDlg.h里面声明 void CTestDlg::threadFunc(void) //在TestDlg. ...
- JavaScript的条件语句
JavaScript的条件语句 1.JavaScript的条件语句包括以下几个 (1)if - 只有当指定条件为true时,使用该语句来执行代码: (2)if...else - 当指定条件为true时 ...
- HDU4549 M斐波那契数列 矩阵快速幂+欧拉函数+欧拉定理
M斐波那契数列 Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 65535/32768 K (Java/Others)Total Sub ...
- CodeForces 651B Beautiful Paintings 贪心
A. Joysticks time limit per test 1 second memory limit per test 256 megabytes input standard input o ...
- ASP.NET文件的上传下载提交分页
<%@ Page Title="" Language="C#" MasterPageFile="~/Site.Master" Auto ...
- 数据库批量修改表名,增加前缀(SQL server)
exec sp_msforeachtable @command1=' declare @o sysname,@n sysname select @o=''?'' ,@n=stuff(@o,1,7,'' ...
- BZOJ 3460 Jc的宿舍
题目链接:http://www.lydsy.com:808/JudgeOnline/problem.php?id=3460 题意:一棵树.每个节点住一个人,这个人打水的时间为Ti.每次查询一个路径.这 ...
- CentOS 7下编译FreeSWITCH 1.6
安装背景: 已经最小化安装CentOS 7. 准备工作: 挂载安装光盘,配置yum本地化安装,配置方法可以参考http://www.cnblogs.com/yoyotl/p/4877439.html. ...