Safari 应用程序扩展:在 HTTPS 页面上加载 HTML 文件
Safari App Extensions: Load HTML file on HTTPS page
我正在开发 Safari 应用程序扩展(因为 Safari 扩展现已正式弃用),我想通过 JS 将一些 HTML 注入到页面中。但是当我向我的 safari-extension://
URL 发出请求时,请求是在没有 SSL 的情况下发出的,Safari 当前阻止混合内容并且不允许以任何方式更改该策略。所以我有两个问题。
如何为我的开发环境解决这个问题?
我在评论中读到 here 生产打包扩展(旧的 Safari 扩展)将使用 SSL 加载资源。 Safari 应用程序扩展也是如此吗?
编辑
我有一个 Apple Developer 帐户,签署了我的扩展程序,但仍然没有成功。
我使用 messaging protocol safari 暴露给 Safari App Extension 以在响应中将 HTML 作为字符串发送。
内容脚本请求HTML模板(JS)
let sendMessage = (msgObj, callback) => {
msgObj.callbackIndex = (safariCallbackCount++).toString();
let callbackKey = msgObj['type']+'_'+msgObj.callbackIndex;
if (typeof callback === 'function')
messageCallbacks[callbackKey] = callback;
safari.extension.dispatchMessage(msgObj['type'], msgObj);
}
sendMessage({type: 'loadTemplate', path: path}, callback );
请注意存储回调函数的 messageCallbacks 散列以及用于索引唯一性的计数器。您正在将消息传递给 Swift 进程,并且在发送多条消息时返回的响应可能会乱序。
SFSafariExtensionHandler 侦听消息并处理 (swift)
func loadTemplate (withPage page: SFSafariPage, withUrl url: URL, withCallbackIndex callbackIndex: String) {
let pathExtention = url.pathExtension
let pathPrefix = url.path.replacingOccurrences(of: "." + pathExtention, with: "", options: .literal, range: nil)
if let filepath = Bundle.main.path(forResource: pathPrefix, ofType: pathExtention) {
do {
let contents = try String(contentsOfFile: filepath, encoding: .utf8)
page.dispatchMessageToScript(withName: "loadTemplate", userInfo: ["htmlData": contents, "callbackIndex": callbackIndex])
} catch {
// contents could not be loaded
NSLog("ERROR CONTENTS COULD NOT BE LOADED FROM \(filepath)")
}
} else {
NSLog("Could not build file path")
}
}
// This method will be called when a content script provided by your extension calls safari.extension.dispatchMessage("message").
override func messageReceived(withName messageName: String, from page: SFSafariPage, userInfo: [String : Any]?) {
page.getPropertiesWithCompletionHandler { properties in
switch messageName {
case "loadTemplate":
self.loadTemplate(withPage: page, withUrl: URL(string: userInfo?["path"] as! String)!, withCallbackIndex: userInfo?["callbackIndex"] as! String)
default:
NSLog("NO DEFINITION FOR STRING VALUE")
}
}
}
内容脚本处理响应 (JS)
let handleMessage = event => {
let callbackIndex = event.message.callbackIndex;
delete event.message.callbackIndex;
let callbackKey = event.name+'_'+callbackIndex;
if ( typeof messageCallbacks[callbackKey] === 'function' ) {
messageCallbacks[callbackKey](event.message);
delete messageCallbacks[callbackKey]
}
};
safari.self.addEventListener("message", handleMessage);
//// html data is accessible from event.message.htmlData
我正在开发 Safari 应用程序扩展(因为 Safari 扩展现已正式弃用),我想通过 JS 将一些 HTML 注入到页面中。但是当我向我的 safari-extension://
URL 发出请求时,请求是在没有 SSL 的情况下发出的,Safari 当前阻止混合内容并且不允许以任何方式更改该策略。所以我有两个问题。
如何为我的开发环境解决这个问题?
我在评论中读到 here 生产打包扩展(旧的 Safari 扩展)将使用 SSL 加载资源。 Safari 应用程序扩展也是如此吗?
编辑
我有一个 Apple Developer 帐户,签署了我的扩展程序,但仍然没有成功。
我使用 messaging protocol safari 暴露给 Safari App Extension 以在响应中将 HTML 作为字符串发送。
内容脚本请求HTML模板(JS)
let sendMessage = (msgObj, callback) => {
msgObj.callbackIndex = (safariCallbackCount++).toString();
let callbackKey = msgObj['type']+'_'+msgObj.callbackIndex;
if (typeof callback === 'function')
messageCallbacks[callbackKey] = callback;
safari.extension.dispatchMessage(msgObj['type'], msgObj);
}
sendMessage({type: 'loadTemplate', path: path}, callback );
请注意存储回调函数的 messageCallbacks 散列以及用于索引唯一性的计数器。您正在将消息传递给 Swift 进程,并且在发送多条消息时返回的响应可能会乱序。
SFSafariExtensionHandler 侦听消息并处理 (swift)
func loadTemplate (withPage page: SFSafariPage, withUrl url: URL, withCallbackIndex callbackIndex: String) {
let pathExtention = url.pathExtension
let pathPrefix = url.path.replacingOccurrences(of: "." + pathExtention, with: "", options: .literal, range: nil)
if let filepath = Bundle.main.path(forResource: pathPrefix, ofType: pathExtention) {
do {
let contents = try String(contentsOfFile: filepath, encoding: .utf8)
page.dispatchMessageToScript(withName: "loadTemplate", userInfo: ["htmlData": contents, "callbackIndex": callbackIndex])
} catch {
// contents could not be loaded
NSLog("ERROR CONTENTS COULD NOT BE LOADED FROM \(filepath)")
}
} else {
NSLog("Could not build file path")
}
}
// This method will be called when a content script provided by your extension calls safari.extension.dispatchMessage("message").
override func messageReceived(withName messageName: String, from page: SFSafariPage, userInfo: [String : Any]?) {
page.getPropertiesWithCompletionHandler { properties in
switch messageName {
case "loadTemplate":
self.loadTemplate(withPage: page, withUrl: URL(string: userInfo?["path"] as! String)!, withCallbackIndex: userInfo?["callbackIndex"] as! String)
default:
NSLog("NO DEFINITION FOR STRING VALUE")
}
}
}
内容脚本处理响应 (JS)
let handleMessage = event => {
let callbackIndex = event.message.callbackIndex;
delete event.message.callbackIndex;
let callbackKey = event.name+'_'+callbackIndex;
if ( typeof messageCallbacks[callbackKey] === 'function' ) {
messageCallbacks[callbackKey](event.message);
delete messageCallbacks[callbackKey]
}
};
safari.self.addEventListener("message", handleMessage);
//// html data is accessible from event.message.htmlData