js执行研究
参考1:《JavaScriptCore解析--基础篇(四) 页面解析与JavaScript元素的执行》
参考2:《Chromium网页DOM Tree创建过程分析》
内嵌js代码执行callstack
> libcef.dll!blink::ScriptController::evaluateScriptInMainWorld(const blink::ScriptSourceCode & sourceCode, blink::AccessControlStatus accessControlStatus, blink::ScriptController::ExecuteScriptPolicy policy, double * compilationFinishTime) Line 557 C++
libcef.dll!blink::ScriptController::executeScriptInMainWorld(const blink::ScriptSourceCode & sourceCode, blink::AccessControlStatus accessControlStatus, double * compilationFinishTime) Line 540 C++
libcef.dll!blink::ScriptLoader::executeScript(const blink::ScriptSourceCode & sourceCode, double * compilationFinishTime) Line 414 C++
libcef.dll!blink::ScriptLoader::prepareScript(const WTF::TextPosition & scriptStartPosition, blink::ScriptLoader::LegacyTypeSupport supportLegacyTypes) Line 272 C++
libcef.dll!blink::HTMLScriptRunner::runScript(blink::Element * script, const WTF::TextPosition & scriptStartPosition) Line 354 C++
libcef.dll!blink::HTMLScriptRunner::execute(WTF::PassRefPtr<blink::Element> scriptElement, const WTF::TextPosition & scriptStartPosition) Line 216 C++
libcef.dll!blink::HTMLDocumentParser::runScriptsForPausedTreeBuilder() Line 331 C++
libcef.dll!blink::HTMLDocumentParser::processParsedChunkFromBackgroundParser(WTF::PassOwnPtr<blink::HTMLDocumentParser::ParsedChunk> popChunk) Line 526 C++
libcef.dll!blink::HTMLDocumentParser::pumpPendingSpeculations() Line 586 C++
libcef.dll!blink::HTMLDocumentParser::resumeParsingAfterYield() Line 320 C++
libcef.dll!blink::HTMLParserScheduler::continueParsing() Line 175 C++
红字部分表示共同被调用的函数
外部引用js代码执行callstack
libcef.dll!blink::ScriptLoader::executeScript(const blink::ScriptSourceCode & sourceCode, double * compilationFinishTime) Line 349 C++
> libcef.dll!blink::HTMLScriptRunner::executePendingScriptAndDispatchEvent(blink::PendingScript & pendingScript, blink::PendingScript::Type pendingScriptType) Line 156 C++
libcef.dll!blink::HTMLScriptRunner::executeParsingBlockingScript() Line 125 C++
libcef.dll!blink::HTMLScriptRunner::executeParsingBlockingScripts() Line 234 C++
libcef.dll!blink::HTMLScriptRunner::executeScriptsWaitingForLoad(blink::Resource * resource) Line 244 C++
libcef.dll!blink::HTMLDocumentParser::notifyScriptLoaded(blink::Resource * cachedResource) Line 1064 C++
libcef.dll!blink::HTMLScriptRunner::notifyFinished(blink::Resource * cachedResource) Line 200 C++
libcef.dll!blink::Resource::checkNotify() Line 252 C++
libcef.dll!blink::Resource::finishOnePart() Line 316 C++
libcef.dll!blink::Resource::finish() Line 323 C++
libcef.dll!blink::ResourceLoader::didFinishLoading(blink::WebURLLoader * __formal, double finishTime, __int64 encodedDataLength) Line 449 C++
libcef.dll!content::WebURLLoaderImpl::Context::OnCompletedRequest(int error_code, bool was_ignored_by_handler, bool stale_copy_in_cache, const std::basic_string<char,std::char_traits<char>,std::allocator<char> > & security_info, const base::TimeTicks & completion_time, __int64 total_transfer_size) Line 747 C++
libcef.dll!content::ResourceDispatcher::OnRequestComplete(int request_id, const ResourceMsg_RequestCompleteData & request_complete_data) Line 396 C++
在HTMLScriptRunner::execute中,首先执行runScript已有的脚本,然后可能还有被阻塞的脚本需要executeParsingBlockingScripts,这里的执行路径类似于下载外部引用的脚本执行路径
资源类文件的下载执行过程与此类似,而主页面的下载则是另一个过程,如下
页面框架html下载及解析
> libcef.dll!blink::HTMLDocumentParser::appendBytes(const char * data, unsigned int length) Line 1125 C++
libcef.dll!blink::DocumentWriter::addData(const char * bytes, unsigned int length) Line 93 C++
libcef.dll!blink::DocumentLoader::commitData(const char * bytes, unsigned int length) Line 540 C++
libcef.dll!blink::DocumentLoader::processData(const char * data, unsigned int length) Line 597 C++
libcef.dll!blink::DocumentLoader::dataReceived(blink::Resource * resource, const char * data, unsigned int length) Line 574 C++
libcef.dll!blink::RawResource::appendData(const char * data, unsigned int length) Line 101 C++
libcef.dll!blink::ResourceLoader::didReceiveData(blink::WebURLLoader * __formal, const char * data, int length, int encodedDataLength) Line 427 C++
libcef.dll!content::WebURLLoaderImpl::Context::OnReceivedData(scoped_ptr<content::RequestPeer::ReceivedData,std::default_delete<content::RequestPeer::ReceivedData> > data) Line 698 C++
libcef.dll!content::ResourceDispatcher::OnReceivedData(int request_id, int data_offset, int data_length, int encoded_data_length) Line 290 C++
html解析background(线程间通讯)
在HTMLDocumentParser::appendByte中,使用线程间通讯发送解析任务到BackgroundHTMLParser::appendRawBytesFromMainThrea
libcef.dll!blink::BackgroundHTMLParser::sendTokensToMainThread>
libcef.dll!blink::BackgroundHTMLParser::pumpTokenizer() Line 259 C++
libcef.dll!blink::BackgroundHTMLParser::appendDecodedBytes(const WTF::String & input) Line 138 C++
>>通知其它线程设置编码
> libcef.dll!blink::BackgroundHTMLParser::updateDocument(const WTF::String & decodedData) Line 160 C++
libcef.dll!blink::BackgroundHTMLParser::appendRawBytesFromMainThread(WTF::PassOwnPtr<WTF::Vector<char,0,WTF::PartitionAllocator> > buffer) Line 130 C++
发送给主线程HTMLDocumentParser::notifyPendingParsedChunks
HTMLParserScheduler::continueParsing
HTMLParserScheduler::scheduleForResume
HTMLDocumentParser::notifyPendingParsedChunks
至此,这里跟内嵌js代码执行过程取得联系
js代码文本执行前的准备
这里可以对js代码文本进行处理,比如替换或屏蔽
bool ScriptLoader::prepareScript(const TextPosition& scriptStartPosition, LegacyTypeSupport supportLegacyTypes)
{
...
...
...
executeScript(ScriptSourceCode(scriptContent(), scriptURL, position)) // 这里执行
// 调用-->
// 这里获取js脚本文本内容
String ScriptLoader::scriptContent() const
{
return m_element->textFromChildren();
}
// 调用-->
// 可能有多段js脚本文本
String Element::textFromChildren()
{
...
Text* text = toText(child); // 代码文本
if (!firstTextNode)
跨域iframe的访问
相关代码
src\third_party\WebKit\Source\core\frame\DOMWindow.cpp
Blocked a frame with origin
bool DOMWindow::isInsecureScriptAccess(LocalDOMWindow& callingWindow, const String& urlString)
String DOMWindow::crossDomainAccessErrorMessage(const LocalDOMWindow* callingWindow) const
call stack
libcef.dll!blink::DOMWindow::crossDomainAccessErrorMessage(const blink::LocalDOMWindow * callingWindow) Line 267 C++
libcef.dll!blink::failedAccessCheckCallbackInMainThread(v8::Local<v8::Object> host, v8::AccessType type, v8::Local<v8::Value> data) Line 306 C++
libcef.dll!v8::internal::Isolate::ReportFailedAccessCheck(v8::internal::Handle<v8::internal::JSObject> receiver) Line 778 C++
> libcef.dll!v8::internal::JSObject::GetPropertyWithFailedAccessCheck(v8::internal::LookupIterator * it) Line 1343 C++
libcef.dll!v8::internal::Object::GetProperty(v8::internal::LookupIterator * it, v8::internal::LanguageMode language_mode) Line 811 C++
libcef.dll!v8::internal::LoadIC::Load(v8::internal::Handle<v8::internal::Object> object, v8::internal::Handle<v8::internal::Name> name) Line 716 C++
disable-web-security
这个设置可能相关的代码
webSecurityEnabled
void SecurityOrigin::grantUniversalAccess()
m_universalAccess
SecurityOrigin::canRequest
如果canRequest返回true,则表示可以访问,否则会被拒绝访问