Web前端开发:跨域XMLHttpRequest处理 - Web前端
作者:98wpeu发布时间:2026-09-13分类:网页前端技术浏览:15

常规网页可以使用 XMLHttpRequest 对象从远程服务器发送和接收数据,但是它们受同一原始策略的限制 。 内容脚本代表已将内容脚本注入其中的WEB起源发起请求,因此,内容脚本也应遵循 相同的起源策略。(自Chrome 73以来,内容脚本一直受CORB的限制,而自chrome 83以来,内容脚本一直受 CORS的限制。)扩展来源不受限制-在扩展的背景页面或前景选项卡中执行的脚本可以与起源以外的远程服务器进行对话,只要该扩展程序请求跨域权限。
扩展原点
每个正在运行的扩展都存在于其自己的单独安全源中。在不请求其他特权的情况下,扩展可以使用xmlhttpRequest来获取其安装中的资源。例如,如果扩展config.json在config_resources文件夹中包含名为的JSON配置文件,则扩展可以像以下方式检索文件的内容:
var xhr = new XMLHTTPRequest();
xhr.onreadystatechange = handleStateChange; // Implemented elsewhere.
xhr.open("get", Chrome.extension.geturl('/config_resources/config.JSon'), true);
xhr.send();如果扩展程序尝试使用其自身以外的其他安全来源,例如https://www.google.com,则浏览器将不允许它,除非扩展程序已请求适当的跨域许可。
请求跨域权限
通过将主机或主机匹配模式(或两者)添加到清单文件的 权限部分 ,该扩展可以请求访问其来源之外的远程服务器。
{
"name": "My extension",
...
"permissions": [
"https://www.jiangweishan.com/"
],
...
}跨域许可权值可以是完全限定的主机名,如下所示:
“ HTTPS://www.Google.com/”
“ https://www.Gmail.com/”
或者它们可以是匹配模式,如下所示:
“ https://*.google.com/”
“ https:// * /”
匹配模式“ https:// * /”允许HTTPS访问所有可访问的域。请注意,此处的匹配模式与内容脚本匹配模式相似,但是主机后面的所有路径信息都将被忽略。
还要注意,访问权限是由主机和方案授予的。如果扩展要对给定主机或一组主机同时进行安全和非安全的HTTP访问,则它必须分别声明权限:
"permissions": [ "http://www.jiangweishan.com/", "https://www.jiangweishan.com/" ]
安全注意事项
避免跨站点脚本漏洞
使用通过XMLHttPRequest检索的资源时,您的后台页面应注意不要成为跨站点脚本的牺牲品。具体来说,请避免使用危险的API,例如:
var xhr = new XMLHttpRequest();
xhr.open("GET", "https://api.example.com/data.json", true);
xhr.onreadystatechange = function() {
if (xhr.readyState == 4) {
// WARNING! Might be evaluating an evil script!
var resp = eval("(" + xhr.responsetext + ")");
...
}
}
xhr.send();var xhr = new XMLHttpRequest();
xhr.open("GET", "https://api.example.com/data.json", true);
xhr.onreadystatechange = function() {
if (xhr.readyState == 4) {
// WARNING! Might be injecting a malicious script!
document.getElementById("resp").innerHTML = xhr.responseText;
...
}
}
xhr.send();相反,请选择不运行脚本的更安全的API:
var xhr = new XMLHttpRequest();
xhr.open("GET", "https://api.example.com/data.json", true);
xhr.onreadystatechange = function() {
if (xhr.readyState == 4) {
// JSON.parse does not evaluate the attacker's scripts.
var resp = JSON.parse(xhr.responseText);
}
}
xhr.send();var xhr = new XMLHttpRequest();
xhr.open("GET", "https://api.example.com/data.json", true);
xhr.onreadystatechange = function() {
if (xhr.readyState == 4) {
// innerText does not let the attacker inject html elements.
document.getElementById("resp").innerText = xhr.responseText;
}
}
xhr.send();限制内容脚本对跨域请求的访问
当代表内容脚本执行跨域请求时,请小心防范可能试图假冒内容脚本的恶意网页。特别是,不允许内容脚本请求任意URL。
考虑一个示例,其中扩展程序执行跨源请求以使内容脚本发现商品价格。一种(不安全的)方法是让内容脚本指定要由后台页面获取的确切资源。
Chrome.runtime.onMessage.addlistener(
function(request, sender, sendResponse) {
if (request.contentScriptQuery == 'fetchUrl') {
// WARNING: SECURITY PROBLEM - a malicious web page may abuse
// the message handler to get access to arbitrary cross-origin
// resources.
Fetch(request.url)
.then(response => response.text())
.then(text => sendResponse(text))
.catch(error => ...)
return true; // Will respond asynchronously.
}
});chrome.runtime.sendMessage(
{contentScriptQuery: 'fetchUrl',
url: 'https://another-site.com/price-query?itemId=' +
encodeURIComponent(request.itemId)},
response => parsePrice(response.text()));在上面的方法中,内容脚本可以要求扩展读取该扩展可以访问的任何URL。恶意网页可能能够伪造此类消息并欺骗该扩展以提供对跨域资源的访问。
而是,设计消息处理程序,以限制可以获取的资源。下方,itemId内容脚本仅提供,而不提供完整的URL。
chrome.runtime.onMessage.addListener(
function(request, sender, sendResponse) {
if (request.contentScriptQuery == 'queryPrice') {
var url = 'https://another-site.com/price-query?itemId=' +
encodeURIComponent(request.itemId);
fetch(url)
.then(response => response.text())
.then(text => parsePrice(text))
.then(price => sendResponse(price))
.catch(error => ...)
return true; // Will respond Asynchronously.
}
});chrome.runtime.sendMessage(
{contentScriptQuery: 'queryPrice', itemId: 12345},
price => ...);在HTTP上优先使用HTTPS
此外,请特别注意通过HTTP检索的资源。如果您的扩展程序用于恶意网络,则网络攻击者(也称为“中间人”)可能会修改响应,并有可能攻击您的扩展程序。相反,请尽可能使用HTTPS。
调整内容安全策略
如果您通过在清单中添加属性来修改应用或扩展程序的默认内容安全策略,则 content_security_policy需要确保允许您要连接的任何主机。虽然默认策略不限制与主机的连接,但是在显式添加connect-srcor default-src 指令时要小心。
相关推荐
- select元素样式化:在本机选择元素和自定义选择元素之间取得平衡 - Web前端
- 使用图像处理优化网站媒体的4个理由 - Web前端
- 简单了解下react中处理API的get与post以及封装应用 - Web前端
- Web前端开发:分享react里的form表单“秘方” - Web前端
- 原生JS发送HTTP请求的方式:XMLHttpRequest.send() - Web前端
- AWS推出了无代码应用构建服务Amazon Honeycode - Web前端
- 深入了解下JavaScript与JSON之间的一些事情 - Web前端
- 初识REST和RESTful API并带您学会编写API - Web前端
- 竞争激烈导致谷歌云关闭“独立区域”项目? - Web前端
- 改变this指向"二人组":apply()和call() - Web前端
- 网页前端技术排行
-
- 1[Web前端]用javascript实现默认图片替代未显示的图片 - Web前端
- 2分析Iconfont-阿里巴巴矢量常用图标库 - Web前端
- 3jQuery实例教程:制作网页中可折叠的面板 - Web前端
- 4【第六章】Foundation之按钮和下拉功能 - Web前端
- 5基于jquery的滚动条滚动固定div(附演示下载) - Web前端
- 6jQuery编写widget的一些技巧分享 - Web前端
- 7分享精心挑选的12款优秀jQuery Ajax分页插件和教程 - Web前端
- 8jQuery实现鼠标移到元素上动态提示消息框效果 - Web前端
- 9在Mac/PC上远程调试iPhone/iPad上的网页 - Web前端
- 最近发表
-
- WordPress随机显示特色图片插件:Random Post Thumbnails
- KeePass实现Chrome浏览器自动填充密码方法一
- LNMP一键包nginx 301强制跳转到https教程
- KeePass实现Chrome浏览器自动填充密码方法二
- #建站# 免费的VPS管理软件Xshell8/Xftp8中文版下载
- 使用Xshell 8连接VPS教程_电脑登录vps的方法
- WordPress评论界面添加烟花????效果
- 不同浏览器书签同步方案:坚果云+Floccus_详细使用教程
- iOS端KeePassXC客户端APP:Strongbox Password Safe
- 给WordPress评论中的Gravatar头像图片添加ALT属性


