看下前端定义 History - Web API | MDN (mozilla.org)
History
History
接口允许操作浏览器的曾经在标签页或者框架里访问的会话历史记录。
属性
History
接口不继承于任何属性。
length 只读
返回一个整数(Integer
),该整数表示会话历史中元素的数目,包括当前加载的页。例如,在一个新的选项卡加载的一个页面中,这个属性返回 1
。
允许 Web 应用程序在历史导航上显式地设置默认滚动恢复行为。此属性可以是自动的(auto
)或者手动的(manual
)。
state 只读
返回一个表示历史堆栈顶部的状态的任意(any
)值。这是一种不必等待 popstate 事件而查看状态的方式。
方法
History
接口不继承任何方法。
此异步方法转到浏览器会话历史的上一页,与用户单击浏览器的 Back 按钮的行为相同。等价于 history.go(-1)
。
调用此方法回到会话历史的第一页之前没有效果并且不会引发异常。
此异步方法转到浏览器会话历史的下一页,与用户单击浏览器的 Forward 按钮的行为相同。等价于 history.go(1)
。
调用此方法超越浏览器历史记录中最新的页面没有效果并且不会引发异常。
通过当前页面的相对位置从浏览器历史记录(会话记录)异步加载页面。比如:参数为 -1 的时候为上一页,参数为 1 的时候为下一页。当你指定了一个越界值(例如:当会话历史记录中没有之前访问的页面时,则传参的值为 -1,那么这个方法没有任何效果也不会报错。调用没有参数的 go()
方法或者参数值为 0 时,重新载入当前页面。Internet Explorer 允许你指定一个字符串,而不是整数,以转到历史记录列表中的特定 URL。
按指定的名称和 URL(如果提供该参数)将数据 push 进会话历史栈,数据被 DOM 进行不透明处理;你可以指定任何可以被序列化的 javascript 对象。请注意,除了 Safari 所有浏览器现在都忽略了 title 参数。更多的信息,请看使用 History API。
按指定的数据、名称和 URL(如果提供该参数),更新 history 栈上最新的条目。这个数据被 DOM 进行了不透明处理。你可以指定任何可以被序列化的 javascript 对象。请注意,除了 Safari 所有浏览器现在都忽略了 title 参数。更多的信息,请看使用 History API。
一、上前端测试代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Test fetch</title>
<script>
window.onload = function (e) {
document.getElementById("go-back").addEventListener("click", (e) => {
window.history.back();
});
};
</script>
</head>
<body>
<button id="go-back">Go back!</button>
</body>
</html>
二、上History 接口c++代码定义
1、接口定义 third_party\blink\renderer\core\frame\history.idl
/*
* Copyright (C) 2007, 2008 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
// https://html.spec.whatwg.org/C/#the-history-interface
enum ScrollRestoration {"auto", "manual"};
[
Exposed=Window
] interface History {
[HighEntropy=Direct, MeasureAs=HistoryLength, RaisesException] readonly attribute unsigned long length;
[Measure, RaisesException] attribute ScrollRestoration scrollRestoration;
[CallWith=ScriptState, RaisesException] readonly attribute any state;
[CallWith=ScriptState, RaisesException] void go(optional long delta = 0);
[CallWith=ScriptState, RaisesException] void back();
[CallWith=ScriptState, RaisesException] void forward();
[CallWith=ScriptState, MeasureAs=HistoryPushState, RaisesException] void pushState(any data, DOMString title, optional DOMString? url = null);
[CallWith=ScriptState, MeasureAs=HistoryReplaceState, RaisesException] void replaceState(any data, DOMString title, optional DOMString? url = null);
};
2、history代码实现类:
{
//前端调用的c++函数实现
void back(ScriptState*, ExceptionState&);
void forward(ScriptState*, ExceptionState&);
void go(ScriptState*, int delta, ExceptionState&);
void pushState(ScriptState*,
const ScriptValue& data,
const String& title,
const String& url,
ExceptionState&);
}
third_party\blink\renderer\core\frame\history.h
third_party\blink\renderer\core\frame\history.cc
/*
* Copyright (C) 2007 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_FRAME_HISTORY_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_FRAME_HISTORY_H_
#include "base/gtest_prod_util.h"
#include "third_party/blink/public/mojom/page_state/page_state.mojom-blink.h"
#include "third_party/blink/public/web/web_frame_load_type.h"
#include "third_party/blink/renderer/bindings/core/v8/serialization/serialized_script_value.h"
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.h"
#include "third_party/blink/renderer/core/loader/frame_loader_types.h"
#include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
#include "third_party/blink/renderer/platform/heap/garbage_collected.h"
#include "third_party/blink/renderer/platform/wtf/forward.h"
namespace blink {
class LocalDOMWindow;
class KURL;
class ExceptionState;
class HistoryItem;
class ScriptState;
// This class corresponds to the History interface.
class CORE_EXPORT History final : public ScriptWrappable,
public ExecutionContextClient {
DEFINE_WRAPPERTYPEINFO();
public:
explicit History(LocalDOMWindow*);
unsigned length(ExceptionState&) const;
ScriptValue state(ScriptState*, ExceptionState&);
void back(ScriptState*, ExceptionState&);
void forward(ScriptState*, ExceptionState&);
void go(ScriptState*, int delta, ExceptionState&);
void pushState(ScriptState*,
const ScriptValue& data,
const String& title,
const String& url,
ExceptionState&);
void replaceState(ScriptState*,
const ScriptValue& data,
const String& title,
const String& url,
ExceptionState& exception_state);
void setScrollRestoration(const String& value, ExceptionState&);
String scrollRestoration(ExceptionState&);
bool IsSameAsCurrentState(SerializedScriptValue*) const;
void Trace(Visitor*) const override;
private:
KURL UrlForState(const String& url);
void StateObjectAdded(scoped_refptr<SerializedScriptValue>,
const String& title,
const String& url,
WebFrameLoadType,
ScriptState*,
ExceptionState&);
SerializedScriptValue* StateInternal() const;
mojom::blink::ScrollRestorationType ScrollRestorationInternal() const;
HistoryItem* GetHistoryItem() const;
scoped_refptr<SerializedScriptValue> last_state_object_requested_;
};
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_CORE_FRAME_HISTORY_H_
3、上调试堆栈:
1)、F:\code\google\src\out\Debug\gen\third_party\blink\renderer\bindings\core\v8\v8_history.cc
void BackOperationCallback(const v8::FunctionCallbackInfo<v8::Value>& info) {
RUNTIME_CALL_TIMER_SCOPE_DISABLED_BY_DEFAULT(info.GetIsolate(), "Blink_History_back");
BLINK_BINDINGS_TRACE_EVENT("History.back");
v8::Isolate* isolate = info.GetIsolate();
v8::Local<v8::Object> v8_receiver = info.This();
History* blink_receiver = V8History::ToWrappableUnsafe(isolate, v8_receiver);
v8::Local<v8::Context> receiver_context = v8_receiver->GetCreationContextChecked();
ScriptState* receiver_script_state = ScriptState::From(receiver_context);
ScriptState* script_state = receiver_script_state;
const ExceptionContextType exception_context_type = ExceptionContextType::kOperationInvoke;
const char* const class_like_name = "History";
const char* const property_name = "back";
ExceptionState exception_state(isolate, exception_context_type, class_like_name, property_name);
blink_receiver->back(script_state, exception_state);
if (UNLIKELY(exception_state.HadException())) {
return;
}
}
2)、F:\code\google\src\third_party\blink\renderer\core\frame\history.cc
void History::back(ScriptState* script_state, ExceptionState& exception_state) {
go(script_state, -1, exception_state);
}
页面打开效果: