上一主题 下一主题
ScriptCat,新一代的脚本管理器脚本站,与全世界分享你的用户脚本油猴脚本开发指南教程目录
返回列表 发新帖

ajaxHooker拦截跨域问题求助

[复制链接]
  • TA的每日心情
    慵懒
    2024-3-12 16:25
  • 签到天数: 1 天

    [LV.1]初来乍到

    1

    主题

    1

    回帖

    5

    积分

    助理工程师

    积分
    5
    发表于 2024-3-12 16:36:25 | 显示全部楼层 | 阅读模式
    悬赏10油猫币已解决

    本帖最后由 sdcsdv 于 2024-3-12 17:41 编辑

    本帖最后由 sdcsdv 于 2024-3-12 16:40 编辑

    计划通过拦截axios请求,实现跨域访问,但发现axios跨域先被浏览器抓到了,请教如何实现拦截跨域访问?
    kuayu.png

    前端代码:

    const onClick = async () => {
      axios.get('https://www.baidu.com/', {})
        .then(res => {
          console.log(res);
        })
        .catch((e) => {
          console.log('获取数据失败');
        });
    };

    油猴代码:

    // ==UserScript==
    // @name         ajaxHooker拦截-2024
    // @namespace    http://tampermonkey.net/
    // @version      0.1
    // @description  try to take over the world!
    // @author       You
    // @match        http://localhost:5173/*
    // @grant        unsafeWindow
    // @grant        GM_xmlhttpRequest
    // @connect      *
    // @require      https://scriptcat.org/lib/637/1.3.3/ajaxHooker.js
    // @run-at       document-start
    // ==/UserScript==
    
    (function() {
        'use strict';
        ajaxHooker.hook(request => {
            console.log('request:', request);
            request.response = res => {
                const responseText = res.responseText; // 注意保存原数据
                res.responseText = new Promise(resolve => {
                    setTimeout(() => {
                        //跨域访问
                        GM_xmlhttpRequest({
                            url: request.url,
                            method: request.method,
                            headers: request.headers,
                            data: request.body,
                            onload: function(res) {
                                console.log('res:', res);
                                //返回修改后数据
                                resolve(res);
                            },
                            onerror: function(error) {
                                console.log('error:', error);
                                reject(error);
                            }
                        });
                        //resolve('test');
                    }, 2000);
                });
            };
        });
    })();

    最佳答案

    查看完整内容

    你的意思是前端直接写跨域吗?那可以保存request.url的值,然后改一个同源url让其正常响应,再替换响应值: 严格来说这不是最理想的方案,会多发生一次不必要的同源请求,因为ajaxHooker的主要目的是在原值上修改,而非整个替换原值,所以没有实现这部分特性。解决方案在那个库下面的回复中也有讨论(151楼),加入异步的话需要处理好事件的触发时机,通用的方案还得劫持更多事件,挺复杂的。 ...
  • TA的每日心情
    慵懒
    2022-3-8 11:41
  • 签到天数: 2 天

    [LV.1]初来乍到

    22

    主题

    881

    回帖

    1379

    积分

    荣誉开发者

    积分
    1379

    荣誉开发者卓越贡献油中2周年生态建设者油中3周年挑战者 lv2

    发表于 2024-3-12 16:36:26 | 显示全部楼层
    你的意思是前端直接写跨域吗?那可以保存request.url的值,然后改一个同源url让其正常响应,再替换响应值:
    1. ajaxHooker.hook(request => {
    2.     const trueUrl = request.url;
    3.     request.url = location.href;
    4.     request.response = res => {
    5.         res.responseText = new Promise(resolve => {
    6.             GM_xmlhttpRequest({
    7.                 url: trueUrl,
    8.                 ....
    9.             });
    10.         });
    11.     };
    12. });
    复制代码

    严格来说这不是最理想的方案,会多发生一次不必要的同源请求,因为ajaxHooker的主要目的是在原值上修改,而非整个替换原值,所以没有实现这部分特性。解决方案在那个库下面的回复中也有讨论(151楼),加入异步的话需要处理好事件的触发时机,通用的方案还得劫持更多事件,挺复杂的。
    回复

    使用道具 举报

  • TA的每日心情
    开心
    6 小时前
  • 签到天数: 213 天

    [LV.7]常住居民III

    305

    主题

    4189

    回帖

    4056

    积分

    管理员

    积分
    4056

    管理员荣誉开发者油中2周年生态建设者喜迎中秋油中3周年挑战者 lv2

    发表于 2024-3-13 09:45:09 | 显示全部楼层
    cxxjackie 发表于 2024-3-12 22:32
    你的意思是前端直接写跨域吗?那可以保存request.url的值,然后改一个同源url让其正常响应,再替换响应值: ...

    给大佬补一下:

    https://bbs.tampermonkey.net.cn/ ... mp;page=16#pid76429

    感觉如果可以拦截请求,然后返回自定义的内容还是挺爽的
    上不慕古,下不肖俗。为疏为懒,不敢为狂。为拙为愚,不敢为恶。
    回复

    使用道具 举报

  • TA的每日心情
    慵懒
    2022-3-8 11:41
  • 签到天数: 2 天

    [LV.1]初来乍到

    22

    主题

    881

    回帖

    1379

    积分

    荣誉开发者

    积分
    1379

    荣誉开发者卓越贡献油中2周年生态建设者油中3周年挑战者 lv2

    发表于 2024-3-13 22:17:15 | 显示全部楼层
    王一之 发表于 2024-3-13 09:45
    给大佬补一下:

    https://bbs.tampermonkey.net.cn/forum.php?mod=viewthread&tid=3284&page=16#pid76429 ...

    是可以做到的,再加一个参数就行了,只是我看着那堆缝缝补补的代码就头大,之前为了兼容各种奇怪的网站加了太多东西,比如我被迫采用defineProperty + Proxy结合的方案,到现在还有一点遗留问题没处理干净。
    吐槽下XMLHttpRequest,这个接口太老旧了,调用繁琐,注入点也非常多,而且由于太繁琐了很多网站还喜欢把他包装一下,导致我的库要与他们共存就成了大问题,很多看起来一步到位的操作需要兜兜转转绕几步来完成。还有xhr实例可以被复用是最草的,相当于一个实例中发生了多次请求,这对异步劫持是个很大挑战,假设前端一边复用xhr一边自己劫持xhr,然后我的库可能还有多个实例在同时运行(多个脚本引用),这中间的兼容问题想想就头秃。反观fetch就好太多了,没有什么open、send这种莫名其妙的接口,一个Promise干净利落,劫持起来是真省心。
    回复

    使用道具 举报

    发表回复

    本版积分规则

    快速回复 返回顶部 返回列表