现代浏览器在浏览器访问的安全上都做了限制,在未经服务端允许的情况下不会跨域发送post数据,如果需要跨域发送post数据,需要服务端进行转发或者代理才能使用。
最近搞了几个浏览器插件,发现插件也遵循浏览器的安全策略,无法发送跨域数据,想将网页中执行的内容通过post接口传送出去不行,只能通过get方式传送,但最近想做一个给企业微信机器人发送消息的插件,企业微信的服务器接口不支持跨域调用。必须通过服务器中转才行。
后来发现油猴脚本里面有一个内置的跨域数据提交的GM_xmlhttpRequest脚本,可以使用它的格式发起跨域请求。
在第一次使用这个跨域请求时,油猴会弹出一个确认页面,确认你是永久授权还是指定域名授权,还是一次性授权脚本插件使用无视安全策略发起跨域请求。
如果是信任环境就选择全部允许,如果不是按需配置。
注意不同的油猴使用的GM_xmlhttpRequest 不一样,tamperMonkey 使用的是GM_xmlhttpRequest函数发起请求,Greasemonkey用的是GM.xmlHttpRequest。
【油猴脚本】GM_xmlhttpRequest跨域请求初探
来自 <https://blog.csdn.net/chirenshuomeng1/article/details/103011165>
油猴官方的一些参考信息:
tamperMonkey官方文档 – @connect
tamperMonkey官方文档 – @GM_xmlhttpRequest
http://www.tampermonkey.net/documentation.php?ext=dhdg#GM_xmlhttpRequest
Greasemonkey的请求示例
另外几种解决跨域post数据传递的方式参考。
1、如果服务端可控的话,可以在服务端配置域名允许跨域请求和接收数据。
2、如果服务端支持jsonp的话,改post 为get 的jsonp格式。
3、如果服务器端不可控,可以考虑使用中转服务器的方式,自己搭建一个代理转发服务器,并将接口允许跨域请求,或与页面相同服务域名,将请求发到自己的服务器,程序接收后再通过服务端发送post请求到最终服务端,其实只要不使用浏览器发送请求,可以随便模拟请求。
4、如果你自己会编译浏览器,可以考虑自己基于开源代码搭建一个适合自己开发需求的,无视安全策略的浏览器。
以下是AIGC 给我的答案,通过油猴插件给企业微信接口发送数据和通知,原理和你给自己服务器同步消息类似。
好的,确实应该使用 GM_xmlHttpRequest
。以下是如何使用 Tampermonkey 的 GM_xmlHttpRequest
来发送跨域请求的详细示例:
使用 GM_xmlHttpRequest 发送跨域请求
确保你的油猴脚本设置正确,包括 @grant GM_xmlHttpRequest
。
- 打开油猴插件,创建新脚本。
- 在脚本编辑器中输入以下代码:
// ==UserScript==
// @name 企业微信机器人消息发送
// @namespace http://tampermonkey.net/
// @version 1.0
// @description 通过企业微信机器人发送消息
// @author 你的名字
// @match *://*/*
// @grant GM_xmlHttpRequest
// ==/UserScript==
(function() {
'use strict';
// 企业微信机器人 Webhook 地址
const webhookUrl = 'https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=你的机器人key';
// 你要发送的消息内容
const messageContent = {
"msgtype": "text",
"text": {
"content": "这是通过油猴插件发送的测试消息"
}
};
// 发送消息的函数
function sendMessage() {
GM_xmlHttpRequest({
method: 'POST',
url: webhookUrl,
headers: {
'Content-Type': 'application/json'
},
data: JSON.stringify(messageContent),
onload: function(response) {
if (response.status === 200) {
console.log('消息发送成功:', response.responseText);
} else {
console.error('消息发送失败:', response);
}
},
onerror: function(error) {
console.error('消息发送失败:', error);
}
});
}
// 这里设置触发消息发送的条件,比如页面加载完成后自动发送
window.addEventListener('load', sendMessage);
})();
详细说明
@grant GM_xmlHttpRequest
: 在脚本的元数据部分,添加了@grant GM_xmlHttpRequest
,这样脚本就能使用GM_xmlHttpRequest
进行跨域请求。GM_xmlHttpRequest
: 这个函数允许发送跨域请求,参数中包括请求方法、URL、请求头和请求体。- 消息内容:
messageContent
是发送的消息,可以根据需要进行修改。 - 触发条件: 在示例中,设置为页面加载完成后自动发送消息,可以根据需要修改为其他触发条件。
调试与测试
- 打开开发者工具控制台:在浏览器中按 F12 或右键点击页面并选择“检查”,然后打开控制台(Console)。
- 检查错误信息:查看控制台中是否有详细的错误信息,有助于定位问题。
其他建议
- 确保 Webhook URL 是正确的:确保
webhookUrl
包含正确的机器人密钥。 - 检查浏览器和 Tampermonkey 的设置:确保浏览器没有其他扩展或设置阻止了请求,并且 Tampermonkey 允许跨域请求。
- 尝试不同的触发条件:如在页面加载完成后,点击按钮来发送消息等。
最终脚本
这是最终的脚本,可以直接复制并在油猴中使用:
// ==UserScript==
// @name 企业微信机器人消息发送
// @namespace http://tampermonkey.net/
// @version 1.0
// @description 通过企业微信机器人发送消息
// @author 你的名字
// @match *://*/*
// @grant GM_xmlHttpRequest
// ==/UserScript==
(function() {
'use strict';
// 企业微信机器人 Webhook 地址
const webhookUrl = 'https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=你的机器人key';
// 你要发送的消息内容
const messageContent = {
"msgtype": "text",
"text": {
"content": "这是通过油猴插件发送的测试消息"
}
};
// 发送消息的函数
function sendMessage() {
GM_xmlHttpRequest({
method: 'POST',
url: webhookUrl,
headers: {
'Content-Type': 'application/json'
},
data: JSON.stringify(messageContent),
onload: function(response) {
if (response.status === 200) {
console.log('消息发送成功:', response.responseText);
} else {
console.error('消息发送失败:', response);
}
},
onerror: function(error) {
console.error('消息发送失败:', error);
}
});
}
// 这里设置触发消息发送的条件,比如页面加载完成后自动发送
window.addEventListener('load', sendMessage);
})();
通过上述脚本,你应该可以使用 Tampermonkey 的 GM_xmlHttpRequest
成功发送跨域请求。如果还有其他问题或需要进一步的帮助,请随时告诉我。