Skip to main content

webFrameMain

웹 페이지와 iframe을 제어한다.

프로세스: 메인

webFrameMain 모듈은 기존 WebContents 인스턴스에서 프레임을 조회하는 데 사용된다. 일반적으로 네비게이션 이벤트 처리 시 활용된다.

const { BrowserWindow, webFrameMain } = require('electron')

const win = new BrowserWindow({ width: 800, height: 1500 })
win.loadURL('https://twitter.com')

win.webContents.on(
'did-frame-navigate',
(event, url, httpResponseCode, httpStatusText, isMainFrame, frameProcessId, frameRoutingId) => {
const frame = webFrameMain.fromId(frameProcessId, frameRoutingId)
if (frame) {
const code = 'document.body.innerHTML = document.body.innerHTML.replaceAll("heck", "h*ck")'
frame.executeJavaScript(code)
}
}
)

WebContents의 mainFrame 속성을 사용해 기존 페이지의 프레임에 접근할 수도 있다.

const { BrowserWindow } = require('electron')

async function main () {
const win = new BrowserWindow({ width: 800, height: 600 })
await win.loadURL('https://reddit.com')

const youtubeEmbeds = win.webContents.mainFrame.frames.filter((frame) => {
try {
const url = new URL(frame.url)
return url.host === 'www.youtube.com'
} catch {
return false
}
})

console.log(youtubeEmbeds)
}

main()

메서드​

이 메서드들은 webFrameMain 모듈에서 접근할 수 있다:

webFrameMain.fromId(processId, routingId)​

  • processId Integer - 프레임을 소유한 프로세스의 내부 ID를 나타내는 Integer 값.
  • routingId Integer - 현재 렌더러 프로세스 내에서 프레임의 고유 ID를 나타내는 Integer 값. 라우팅 ID는 WebFrameMain 인스턴스(frame.routingId)에서 가져올 수 있으며, 프레임 관련 WebContents 네비게이션 이벤트(예: did-frame-navigate)를 통해 전달된다.

반환 값: WebFrameMain | undefined - 주어진 프로세스 ID와 라우팅 ID에 해당하는 프레임을 반환한다. 해당 ID와 연결된 WebFrameMain이 없으면 undefined를 반환한다.

Class: WebFrameMain​

프로세스: 메인
이 클래스는 'electron' 모듈에서 직접 내보내지 않는다. Electron API의 다른 메서드 반환값으로만 사용할 수 있다.

인스턴스 이벤트​

이벤트: 'dom-ready'​

문서가 로드되면 발생한다.

인스턴스 메서드​

frame.executeJavaScript(code[, userGesture])​

  • code string
  • userGesture boolean (선택 사항) - 기본값은 false.

반환값: Promise<unknown> - 실행된 코드의 결과로 이행되거나, 실행 중 오류가 발생하거나 거부된 Promise가 반환되면 거부되는 Promise.

페이지 내에서 code를 평가한다.

브라우저 윈도우에서 requestFullScreen과 같은 일부 HTML API는 사용자의 제스처를 통해서만 호출할 수 있다. userGesture를 true로 설정하면 이 제한을 해제한다.

frame.reload()​

boolean 타입을 반환한다. 리로드가 성공적으로 시작되었는지 여부를 나타낸다. 프레임에 히스토리가 없는 경우에만 false를 반환한다.

frame.isDestroyed()​

boolean 타입의 값을 반환한다. 프레임이 파괴되었는지 여부를 나타낸다.

frame.send(channel, ...args)​

  • channel string
  • ...args any[]

channel을 통해 렌더러 프로세스로 비동기 메시지를 보낸다. 이때 추가 인자를 함께 전달할 수 있다. 전달된 인자는 postMessage와 마찬가지로 Structured Clone Algorithm을 사용해 직렬화된다. 따라서 프로토타입 체인은 포함되지 않는다. 함수, Promise, Symbol, WeakMap, WeakSet을 전달하려고 하면 예외가 발생한다.

렌더러 프로세스는 ipcRenderer 모듈을 사용해 channel을 구독하여 이 메시지를 처리할 수 있다.

frame.postMessage(channel, message, [transfer])​

  • channel string
  • message any
  • transfer MessagePortMain[] (선택 사항)

렌더러 프로세스로 메시지를 보내며, 선택적으로 하나 이상의 MessagePortMain 객체의 소유권을 이전할 수 있다.

이전된 MessagePortMain 객체는 렌더러 프로세스에서 이벤트의 ports 속성을 통해 접근할 수 있다. 렌더러 프로세스에 도착하면 이 객체는 네이티브 DOM MessagePort 객체로 변환된다.

예를 들어:

// 메인 프로세스
const win = new BrowserWindow()
const { port1, port2 } = new MessageChannelMain()
win.webContents.mainFrame.postMessage('port', { message: 'hello' }, [port1])

// 렌더러 프로세스
ipcRenderer.on('port', (e, msg) => {
const [port] = e.ports
// ...
})

frame.collectJavaScriptCallStack() 실험적 기능​

Promise<string> | Promise<void>를 반환한다. 이 Promise는 현재 실행 중인 자바스크립트 호출 스택과 함께 resolve된다. 만약 프레임에서 자바스크립트가 실행되지 않으면, 이 Promise는 resolve되지 않는다. 호출 스택을 수집할 수 없는 경우에는 undefined를 반환한다.

이 기능은 오랜 시간 동안 실행되는 자바스크립트로 인해 프레임이 응답하지 않는 경우, 그 원인을 파악하는 데 유용하다. 더 자세한 정보는 제안된 Crash Reporting API를 참고하면 된다.

const { app } = require('electron')

app.commandLine.appendSwitch('enable-features', 'DocumentPolicyIncludeJSCallStacksInCrashReports')

app.on('web-contents-created', (_, webContents) => {
webContents.on('unresponsive', async () => {
// 실행을 중단하고 응답하지 않는 렌더러의 호출 스택을 수집
const callStack = await webContents.mainFrame.collectJavaScriptCallStack()
console.log('Renderer unresponsive\n', callStack)
})
})

인스턴스 속성​

frame.ipc 읽기 전용​

프레임에 스코프가 지정된 IpcMain 인스턴스다.

ipcRenderer.send, ipcRenderer.sendSync, 또는 ipcRenderer.postMessage로 전송된 IPC 메시지는 다음 순서로 전달된다:

  1. contents.on('ipc-message')
  2. contents.mainFrame.on(channel)
  3. contents.ipc.on(channel)
  4. ipcMain.on(channel)

invoke로 등록된 핸들러는 다음 순서로 확인된다. 정의된 첫 번째 핸들러가 호출되며, 나머지는 무시된다:

  1. contents.mainFrame.handle(channel)
  2. contents.handle(channel)
  3. ipcMain.handle(channel)

대부분의 경우, WebContents의 메인 프레임만 IPC 메시지를 주고받을 수 있다. 하지만 nodeIntegrationInSubFrames 옵션이 활성화된 경우, 자식 프레임도 IPC 메시지를 주고받을 수 있다. nodeIntegrationInSubFrames가 활성화되지 않은 경우, WebContents.ipc 인터페이스가 더 편리할 수 있다.

frame.url 읽기 전용​

프레임의 현재 URL을 나타내는 문자열이다.

frame.origin 읽기 전용​

frame.origin은 RFC 6454에 따라 직렬화된 현재 프레임의 오리진을 나타내는 문자열이다. 이 값은 URL과 다를 수 있다. 예를 들어, 프레임이 about:blank로 열린 자식 윈도우인 경우, frame.origin은 부모 프레임의 오리진을 반환하지만, frame.url은 빈 문자열을 반환한다. scheme/host/port 삼중 구조가 없는 페이지의 경우, 직렬화된 오리진은 "null"이 된다. (즉, n, u, l, l 문자를 포함한 문자열)

frame.top 읽기 전용​

frame이 속한 프레임 계층 구조에서 최상위 프레임을 나타내는 WebFrameMain | null 타입의 값이다.

frame.parent 읽기 전용​

frame.parent는 frame의 상위 프레임을 나타내는 WebFrameMain | null 타입의 프로퍼티이다. 만약 frame이 프레임 계층 구조에서 최상위 프레임이라면, 이 프로퍼티는 null 값을 가진다.

frame.frames 읽기 전용​

frame의 직계 하위 요소를 포함하는 WebFrameMain[] 컬렉션이다.

frame.framesInSubtree 읽기 전용​

frame.framesInSubtree는 frame의 하위 트리에 속한 모든 프레임을 포함하는 WebFrameMain[] 컬렉션이다. 이 컬렉션은 자기 자신도 포함한다. 모든 프레임을 순회할 때 유용하게 사용할 수 있다.

frame.frameTreeNodeId 읽기 전용​

frame.frameTreeNodeId는 프레임의 내부 FrameTreeNode 인스턴스의 ID를 나타내는 정수(Integer) 값이다. 이 ID는 브라우저 전역에서 유효하며, 콘텐츠를 호스팅하는 프레임을 고유하게 식별한다. 이 식별자는 프레임이 생성될 때 고정되며, 프레임의 수명 동안 변하지 않는다. 프레임이 제거되면 해당 ID는 다시 사용되지 않는다.

frame.name 읽기 전용​

프레임의 이름을 나타내는 문자열이다.

frame.osProcessId 읽기 전용​

이 프레임을 소유한 프로세스의 운영체제 pid를 나타내는 정수(Integer) 값이다.

frame.processId 읽기 전용​

이 프레임을 소유한 프로세스의 Chromium 내부 pid를 나타내는 정수 값이다.
이 값은 운영체제의 프로세스 ID와 다르다. 운영체제의 프로세스 ID를 확인하려면 frame.osProcessId를 사용한다.

frame.routingId 읽기 전용​

routingId는 현재 렌더러 프로세스 내에서 유일한 프레임 ID를 나타내는 정수(integer) 값이다. 동일한 기본 프레임을 참조하는 서로 다른 WebFrameMain 인스턴스들은 동일한 routingId를 가진다.

frame.visibilityState 읽기 전용​

프레임의 가시성 상태를 나타내는 문자열이다.

Page Visibility API가 다른 Electron API에 의해 어떻게 영향을 받는지도 참고한다.

frame.detached 읽기 전용​

frame.detached는 프레임이 프레임 트리에서 분리되었는지 여부를 나타내는 불리언 값이다. 만약 페이지가 unload 이벤트 리스너를 실행 중일 때 프레임에 접근하면, 새로 네비게이션된 페이지가 프레임 트리에서 해당 프레임을 대체하면서 프레임이 분리될 수 있다.