開發chrome插件時遇到的一些問題
背景:在一個運作在chrome浏覽器上web應用基礎上開發插件,web應用的協定為https。
chrome插件開發相關知識:https://www.cnblogs.com/liuxianan/p/chrome-plugin-develop.html
chrome官網:https://developer.chrome.com/extensions
由于需要在content_script中調用後端接口(接口協定為http),且接口域名和web應用部署的域名不一緻,固需解決跨域問題。
根據以往經驗,大緻有以下三種方式:
- 後端設定Access-Control-Allow-Origin
- 使用jsonp調用
- 使用iframe
運作時報錯:Mixed Content: The page at XXXX was loaded over HTTPS, but requested XXXX. This request has been blocked; the content must be served over HTTPS.
原因:http請求沒有加密,容易受到MITM攻擊,導緻https連接配接被劫持,是以chrome在某個版本之後(具體哪個版本沒有去查)就禁止了在https中擷取http資源。
分析:以上三種方式都沒有辦法直接繞開http協定,最直接的就是讓背景接口支援https調用就行(安全性而言也能有所提高)。還有一種方式是,在content_script 中将請求轉發至 background,再在background中請求背景。
将http更新成https是肯定沒有問題的,是以這裡對第二種方案在進行可行性研究。
content_script中發送消息給background
chrome.extension.sendMessage({uri:"xdd_add",data:{content:content,title:title},url:"http://localhost:8080/elephant/plugin/savePub"}, function(response) {
console.info("xdd_add",response);
});
background中監聽消息,并請求後端接口
chrome.extension.onMessage.addListener(function(request, sender, sendResponse) {
console.log("Request comes from content script " + sender.tab.url);
dc(request,sendResponse);
//由于需要異步調用sendResponse,是以需要加上return true,通知sendResponse函數等待調用
return true;
});
/**
* dispatch controller
*/
function dc(request,sendResponse){
if (request.uri == "xdd_add") {
//這裡用到jQuery,需注意不能通過遠端擷取js,需要将script下載下傳到本地并打包到插件中
$.ajax({
url:request.url,
data:request.data,
success:function(result){
console.info(result);
sendResponse(result);
}
});
}
}
這裡需要在manifest.json檔案中的permissions設定相關url,才能進行跨域請求:
"permissions": [
"http://localhost:8080"
],
如果沒有這麼做的話,還是會受到同源政策的限制,進而請求失敗。當然你也可以這麼做:
後端設定Access-Control-Allow-Origin
//這裡xxxxxxxxxxxxxxxxxxxxxxxxx 是指你的插件id
httpServletResponse.setHeader("Access-Control-Allow-Origin","chrome-extension://xxxxxxxxxxxxxxxxxxxxxxxxx");
這裡之是以沒有用jsonp方式,是因為CSP(Content Security Policy)。
具體文檔:https://div.io/topic/1669
jsonp是同過
<script>
标簽來加載資源的,它在CSP的限制範圍内。