国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

旁門(mén)左道:借助 HttpClientHandler 攔截請(qǐng)求,體驗(yàn) Semantic Kernel 插件

這篇具有很好參考價(jià)值的文章主要介紹了旁門(mén)左道:借助 HttpClientHandler 攔截請(qǐng)求,體驗(yàn) Semantic Kernel 插件。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問(wèn)。

前天嘗試通過(guò) one-api + dashscope(阿里云靈積) + qwen(通義千問(wèn))運(yùn)行 Semantic Kernel 插件(Plugin) ,結(jié)果嘗試失敗,詳見(jiàn)前天的博文。

今天換一種方式嘗試,選擇了一個(gè)旁門(mén)左道走走看,看能不能在不使用大模型的情況下讓 Semantic Kernel 插件運(yùn)行起來(lái),這個(gè)旁門(mén)左道就是從 Stephen Toub 那偷學(xué)到的一招 —— 借助 DelegatingHandler(new HttpClientHandler()) 攔截 HttpClient 請(qǐng)求,直接以模擬數(shù)據(jù)進(jìn)行響應(yīng)。

先創(chuàng)建一個(gè) .NET 控制臺(tái)項(xiàng)目

dotnet new console
dotnet add package Microsoft.SemanticKernel
dotnet add package Microsoft.Extensions.Http

參照 Semantic Kernel 源碼中的示例代碼創(chuàng)建一個(gè)非常簡(jiǎn)單的插件 LightPlugin

public class LightPlugin
{
    public bool IsOn { get; set; } = false;

    [KernelFunction]
    [Description("幫看一下燈是開(kāi)是關(guān)")]
    public string GetState() => IsOn ? "on" : "off";

    [KernelFunction]
    [Description("開(kāi)燈或者關(guān)燈")]
    public string ChangeState(bool newState)
    {
        IsOn = newState;
        var state = GetState();
        Console.WriteLine(state == "on" ? $"[開(kāi)燈啦]" : "[關(guān)燈咯]");
        return state;
    }
}

接著創(chuàng)建旁門(mén)左道 BackdoorHandler,先實(shí)現(xiàn)一個(gè)最簡(jiǎn)單的功能,打印 HttpClient 請(qǐng)求內(nèi)容

public class BypassHandler() : DelegatingHandler(new HttpClientHandler())
{
    protected override async Task<HttpResponseMessage> SendAsync(
        HttpRequestMessage request, CancellationToken cancellationToken)
    {
        Console.WriteLine(await request.Content!.ReadAsStringAsync());
        // return await base.SendAsync(request, cancellationToken);
        return new HttpResponseMessage(HttpStatusCode.OK);
    }
}

然后攜 LightPluginBypassHandler 創(chuàng)建 Semantic Kernel 的 Kernel

var builder = Kernel.CreateBuilder();
builder.Services.AddOpenAIChatCompletion("qwen-max", "sk-xxxxxx");
builder.Services.ConfigureHttpClientDefaults(b =>
    b.ConfigurePrimaryHttpMessageHandler(() => new BypassHandler()));
builder.Plugins.AddFromType<LightPlugin>();
Kernel kernel = builder.Build();

再然后,發(fā)送攜帶 prompt 的請(qǐng)求并獲取響應(yīng)內(nèi)容

var history = new ChatHistory();
history.AddUserMessage("請(qǐng)開(kāi)燈");
Console.WriteLine("User > " + history[0].Content);
var chatCompletionService = kernel.GetRequiredService<IChatCompletionService>();

// Enable auto function calling
OpenAIPromptExecutionSettings openAIPromptExecutionSettings = new()
{
    ToolCallBehavior = ToolCallBehavior.AutoInvokeKernelFunctions
};

var result = await chatCompletionService.GetChatMessageContentAsync(
    history,
    executionSettings: openAIPromptExecutionSettings,
    kernel: kernel);

Console.WriteLine("Assistant > " + result);

運(yùn)行控制臺(tái)程序,BypassHandler 就會(huì)在控制臺(tái)輸出請(qǐng)求的 json 內(nèi)容(為了閱讀方便對(duì)json進(jìn)行了格式化):

點(diǎn)擊查看 json
{
  "messages": [
    {
      "content": "Assistant is a large language model.",
      "role": "system"
    },
    {
      "content": "\u8BF7\u5F00\u706F",
      "role": "user"
    }
  ],
  "temperature": 1,
  "top_p": 1,
  "n": 1,
  "presence_penalty": 0,
  "frequency_penalty": 0,
  "model": "qwen-max",
  "tools": [
    {
      "function": {
        "name": "LightPlugin-GetState",
        "description": "\u5E2E\u770B\u4E00\u4E0B\u706F\u662F\u5F00\u662F\u5173",
        "parameters": {
          "type": "object",
          "required": [],
          "properties": {}
        }
      },
      "type": "function"
    },
    {
      "function": {
        "name": "LightPlugin-ChangeState",
        "description": "\u5F00\u706F\u6216\u8005\u5173\u706F",
        "parameters": {
          "type": "object",
          "required": [
            "newState"
          ],
          "properties": {
            "newState": {
              "type": "boolean"
            }
          }
        }
      },
      "type": "function"
    }
  ],
  "tool_choice": "auto"
}

為了能反序列化這個(gè) json ,我們需要定義一個(gè)類型 ChatCompletionRequest,Sermantic Kernel 中沒(méi)有現(xiàn)成可以使用的,實(shí)現(xiàn)代碼如下:

點(diǎn)擊查看 ChatCompletionRequest
public class ChatCompletionRequest
{
    [JsonPropertyName("messages")]
    public IReadOnlyList<RequestMessage>? Messages { get; set; }

    [JsonPropertyName("temperature")]
    public double Temperature { get; set; } = 1;

    [JsonPropertyName("top_p")]
    public double TopP { get; set; } = 1;

    [JsonPropertyName("n")]
    public int? N { get; set; } = 1;

    [JsonPropertyName("presence_penalty")]
    public double PresencePenalty { get; set; } = 0;

    [JsonPropertyName("frequency_penalty")]
    public double FrequencyPenalty { get; set; } = 0;

    [JsonPropertyName("model")]
    public required string Model { get; set; }

    [JsonPropertyName("tools")]
    public IReadOnlyList<Tool>? Tools { get; set; }

    [JsonPropertyName("tool_choice")]
    public string? ToolChoice { get; set; }
}

public class RequestMessage
{
    [JsonPropertyName("role")]
    public string? Role { get; set; }

    [JsonPropertyName("name")]
    public string? Name { get; set; }

    [JsonPropertyName("content")]
    public string? Content { get; set; }
}

public class Tool
{
    [JsonPropertyName("function")]
    public FunctionDefinition? Function { get; set; }

    [JsonPropertyName("type")]
    public string? Type { get; set; }
}

public class FunctionDefinition
{
    [JsonPropertyName("name")]
    public string? Name { get; set; }

    [JsonPropertyName("description")]
    public string? Description { get; set; }

    [JsonPropertyName("parameters")]
    public ParameterDefinition Parameters { get; set; }

    public struct ParameterDefinition
    {
        [JsonPropertyName("type")]
        public required string Type { get; set; }

        [JsonPropertyName("description")]
        public string? Description { get; set; }

        [JsonPropertyName("required")]
        public string[]? Required { get; set; }

        [JsonPropertyName("properties")]
        public Dictionary<string, PropertyDefinition>? Properties { get; set; }

        public struct PropertyDefinition
        {
            [JsonPropertyName("type")]
            public required PropertyType Type { get; set; }
        }

        [JsonConverter(typeof(JsonStringEnumConverter))]
        public enum PropertyType
        {
            Number,
            String,
            Boolean
        }
    }
}

有了這個(gè)類,我們就可以從請(qǐng)求中獲取對(duì)應(yīng) Plugin 的 function 信息,比如下面的代碼:

var function = chatCompletionRequest?.Tools.FirstOrDefault(x => x.Function.Description.Contains("開(kāi)燈"))?.Function;
var functionName = function.Name;
var parameterName = function.Parameters.Properties.FirstOrDefault(x => x.Value.Type == PropertyType.Boolean).Key;

接下來(lái)就是旁門(mén)左道的關(guān)鍵,直接在 BypassHandler 中響應(yīng) Semantic Kernel 通過(guò) OpenAI.ClientCore 發(fā)出的 http 請(qǐng)求。

首先創(chuàng)建用于 json 序列化的類 ChatCompletionResponse

點(diǎn)擊查看 ChatCompletionResponse
public class ChatCompletionResponse
{
    [JsonPropertyName("id")]
    public string? Id { get; set; }

    [JsonPropertyName("object")]
    public string? Object { get; set; }

    [JsonPropertyName("created")]
    public long Created { get; set; }

    [JsonPropertyName("model")]
    public string? Model { get; set; }

    [JsonPropertyName("usage"), JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
    public Usage? Usage { get; set; }

    [JsonPropertyName("choices")]
    public List<Choice>? Choices { get; set; }
}

public class Choice
{
    [JsonPropertyName("message")]
    public ResponseMessage? Message { get; set; }

    /// <summary>
    /// The message in this response (when streaming a response).
    /// </summary>
    [JsonPropertyName("delta"), JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
    public ResponseMessage? Delta { get; set; }

    [JsonPropertyName("finish_reason")]
    public string? FinishReason { get; set; }

    /// <summary>
    /// The index of this response in the array of choices.
    /// </summary>
    [JsonPropertyName("index")]
    public int Index { get; set; }
}

public class ResponseMessage
{
    [JsonPropertyName("role")]
    public string? Role { get; set; }

    [JsonPropertyName("name"), JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
    public string? Name { get; set; }

    [JsonPropertyName("content"), JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
    public string? Content { get; set; }

    [JsonPropertyName("tool_calls")]
    public IReadOnlyList<ToolCall>? ToolCalls { get; set; }
}

public class ToolCall
{
    [JsonPropertyName("id")]
    public string? Id { get; set; }

    [JsonPropertyName("function")]
    public FunctionCall? Function { get; set; }

    [JsonPropertyName("type")]
    public string? Type { get; set; }
}

public class Usage
{
    [JsonPropertyName("prompt_tokens")]
    public int PromptTokens { get; set; }

    [JsonPropertyName("completion_tokens")]
    public int CompletionTokens { get; set; }

    [JsonPropertyName("total_tokens")]
    public int TotalTokens { get; set; }
}

public class FunctionCall
{
    [JsonPropertyName("name")]
    public string Name { get; set; } = string.Empty;

    [JsonPropertyName("arguments")]
    public string Arguments { get; set; } = string.Empty;
}

先試試不執(zhí)行 function calling ,直接以 assistant 角色回復(fù)一句話

public class BypassHandler() : DelegatingHandler(new HttpClientHandler())
{
    protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
    {
        var chatCompletion = new ChatCompletionResponse
        {
            Id = Guid.NewGuid().ToString(),
            Model = "fake-mode",
            Object = "chat.completion",
            Created = DateTimeOffset.Now.ToUnixTimeSeconds(),
            Choices =
               [
                   new()
                   {
                       Message = new ResponseMessage
                       {
                           Content = "自己動(dòng)手,豐衣足食",
                           Role = "assistant"
                       },
                       FinishReason = "stop"
                   }
               ]
        };

        var json = JsonSerializer.Serialize(chatCompletion, GetJsonSerializerOptions());
        return new HttpResponseMessage
        {
            Content = new StringContent(json, Encoding.UTF8, "application/json")
        };
    }
}

運(yùn)行控制臺(tái)程序,輸出如下:

User > 請(qǐng)開(kāi)燈
Assistant > 自己動(dòng)手,豐衣足食

成功響應(yīng),到此,旁門(mén)左道成功了一半。

接下來(lái)在之前創(chuàng)建的 chatCompletion 基礎(chǔ)上添加針對(duì) function calling 的 ToolCall 部分。

先準(zhǔn)備好 ChangeState(bool newState) 的參數(shù)值

Dictionary<string, bool> arguments = new()
{
    { parameterName, true }
};

并將回復(fù)內(nèi)容由 "自己動(dòng)手,豐衣足食" 改為 "客官,燈已開(kāi)"

Message = new ResponseMessage
{
    Content = "客官,燈已開(kāi)",
    Role = "assistant"
}

然后為 chatCompletion 創(chuàng)建 ToolCalls 實(shí)例用于響應(yīng) function calling

var messages = chatCompletionRequest.Messages;
if (messages.First(x => x.Role == "user").Content.Contains("開(kāi)燈") == true)
{
    chatCompletion.Choices[0].Message.ToolCalls = new List<ToolCall>()
    {
        new ToolCall
        {
            Id = Guid.NewGuid().ToString(),
            Type = "function",
            Function = new FunctionCall
            {
                Name = function.Name,
                Arguments = JsonSerializer.Serialize(arguments, GetJsonSerializerOptions())
            }
        }
    };
}

運(yùn)行控制臺(tái)程序看看效果

User > 請(qǐng)開(kāi)燈
[開(kāi)燈啦]
[開(kāi)燈啦]
[開(kāi)燈啦]
[開(kāi)燈啦]
[開(kāi)燈啦]
Assistant > 客官,燈已開(kāi)

耶!成功開(kāi)燈!但是,竟然開(kāi)了5次,差點(diǎn)把燈給開(kāi)爆了。

BypassHandler 中打印一下請(qǐng)求內(nèi)容看看哪里出了問(wèn)題

var json = await request.Content!.ReadAsStringAsync();
Console.WriteLine(json);

原來(lái)分別請(qǐng)求/響應(yīng)了5次,第2次請(qǐng)求開(kāi)始,json 中 messages 部分多了 tool_callstool_call_id 內(nèi)容

{
  "messages": [
    {
      "content": "\u5BA2\u5B98\uFF0C\u706F\u5DF2\u5F00",
      "tool_calls": [
        {
          "function": {
            "name": "LightPlugin-ChangeState",
            "arguments": "{\u0022newState\u0022:true}"
          },
          "type": "function",
          "id": "76f8dead-b5ad-4e6d-b343-7f78d68fac8e"
        }
      ],
      "role": "assistant"
    },
    {
      "content": "on",
      "tool_call_id": "76f8dead-b5ad-4e6d-b343-7f78d68fac8e",
      "role": "tool"
    }
  ]
}

這時(shí)恍然大悟,之前 AI assistant 對(duì) function calling 的響應(yīng)只是讓 Plugin 執(zhí)行對(duì)應(yīng)的 function,assistant 還需要根據(jù)執(zhí)行的結(jié)果決定下一下做什么,第2次請(qǐng)求中的 tool_callstool_call_id 就是為了告訴 assistant 執(zhí)行的結(jié)果,所以,還需要針對(duì)這個(gè)請(qǐng)求進(jìn)行專門(mén)的響應(yīng)。

到了旁門(mén)左道最后100米沖刺的時(shí)刻!

RequestMessage 添加 ToolCallId 屬性

public class RequestMessage
{
    [JsonPropertyName("role")]
    public string? Role { get; set; }

    [JsonPropertyName("name")]
    public string? Name { get; set; }

    [JsonPropertyName("content")]
    public string? Content { get; set; }

    [JsonPropertyName("tool_call_id")]
    public string? ToolCallId { get; set; }
}

BypassHandler 中響應(yīng)時(shí)判斷一下 ToolCallId,如果是針對(duì) Plugin 的 function 執(zhí)行結(jié)果的請(qǐng)求,只返回 Message.Content,不進(jìn)行 function calling 響應(yīng)

var messages = chatCompletionRequest.Messages;
var toolCallId = "76f8dead- b5ad-4e6d-b343-7f78d68fac8e";
var toolCallIdMessage = messages.FirstOrDefault(x => x.Role == "tool" && x.ToolCallId == toolCallId);

if (toolCallIdMessage != null && toolCallIdMessage.Content == "on")
{
    chatCompletion.Choices[0].Message.Content = "客官,燈已開(kāi)";
}
else if (messages.First(x => x.Role == "user").Content.Contains("開(kāi)燈") == true)
{  
    chatCompletion.Choices[0].Message.Content = "";
    //..
}

改進(jìn)代碼完成,到了最后10米沖刺的時(shí)刻,再次運(yùn)行控制臺(tái)程序

User > 請(qǐng)開(kāi)燈
[開(kāi)燈啦]
Assistant > 客官,燈已開(kāi)

只有一次開(kāi)燈,沖刺成功,旁門(mén)左道走通,用這種方式體驗(yàn)一下 Semantic Kernel Plugin,也別有一番風(fēng)味。

完整示例代碼已上傳到 github https://github.com/cnblogs-dudu/sk-plugin-sample-101文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-827648.html

到了這里,關(guān)于旁門(mén)左道:借助 HttpClientHandler 攔截請(qǐng)求,體驗(yàn) Semantic Kernel 插件的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來(lái)自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • VUE3 請(qǐng)求攔截器 響應(yīng)攔截器

    1,導(dǎo)入axios? (使用axios進(jìn)行接口的請(qǐng)求,頁(yè)面發(fā)送http請(qǐng)求,很多情況我們要對(duì)請(qǐng)求和其響應(yīng)進(jìn)行特定的處理,如:判斷token,設(shè)置請(qǐng)求頭。如果請(qǐng)求數(shù)非常多,單獨(dú)對(duì)每一個(gè)請(qǐng)求進(jìn)行處理會(huì)變得非常麻煩,程序的優(yōu)雅性也會(huì)大打折扣。所以axios為開(kāi)發(fā)者提供了這樣一個(gè)API:攔

    2024年02月16日
    瀏覽(25)
  • vue請(qǐng)求攔截統(tǒng)一給所有請(qǐng)求加loading

    需求:在項(xiàng)目開(kāi)發(fā)過(guò)程中通常會(huì)給請(qǐng)求加loading,每次發(fā)請(qǐng)求單獨(dú)加loading費(fèi)事費(fèi)力。 思路:用h5做手機(jī)端項(xiàng)目,業(yè)務(wù)簡(jiǎn)單,統(tǒng)一封裝loading,由于vue組件化開(kāi)發(fā),通常是用ajax封裝后的axios插件進(jìn)行,在請(qǐng)求攔截里面可以加loading,接口返回?cái)r截器里面關(guān)閉loading。 具體實(shí)現(xiàn)過(guò)程

    2024年01月23日
    瀏覽(21)
  • XMLHttpRequest攔截請(qǐng)求和響應(yīng)

    環(huán)境: angular 實(shí)現(xiàn): 攔截請(qǐng)求 向請(qǐng)求信息增加字段 ??????????? 攔截響應(yīng) 過(guò)濾返回值 響應(yīng)攔截: 根據(jù)angular使用的XMLHttpRequest 將對(duì)原本的請(qǐng)求轉(zhuǎn)移到另一個(gè)將監(jiān)聽(tīng)返回事件掛載到另一個(gè)世紀(jì)發(fā)送請(qǐng)求的xml上 使用get set 將客戶端獲取的responseText和response按照自己的意愿返

    2024年02月07日
    瀏覽(18)
  • Taro+VantUI請(qǐng)求攔截處理

    請(qǐng)求攔截處理 備注: CONF.baseUrl 需要在config-index.js文件中進(jìn)行配置 代碼如下:

    2024年02月12日
    瀏覽(16)
  • axios 請(qǐng)求和響應(yīng)攔截器

    1. 創(chuàng)建實(shí)例 使用 axios.create() 使用自定義配置創(chuàng)建一個(gè) axios 實(shí)例。 2. 攔截器 在請(qǐng)求或響應(yīng)被 then 或者 catch 處理前攔截他們,攔截分為請(qǐng)求攔截和響應(yīng)攔截。 2.1 request 攔截器,全局添加市場(chǎng)信息 removeMarketCode 是否移除市場(chǎng)信息,默認(rèn)不移除; 根據(jù)上述代碼可以看到,市場(chǎng)信

    2024年02月09日
    瀏覽(25)
  • Feign請(qǐng)求及響應(yīng)攔截器

    feign請(qǐng)求攔截,處理head、param、body參數(shù),附加解密定制化處理,也可以使用原生解碼器; feign響應(yīng)攔截,處理head、param、body參數(shù),附加解密定制化處理,也可以使用原生解碼器; 附件加解密工具(支持格式化rn、rt)等格式化代碼加解密,五年驗(yàn)證品質(zhì)保證

    2024年02月11日
    瀏覽(22)
  • Burp Suite如何攔截站點(diǎn)請(qǐng)求

    Burp Suite如何攔截站點(diǎn)請(qǐng)求

    Burp Suite是一款強(qiáng)大的Web滲透測(cè)試工具,可以用于攔截、修改和分析Web應(yīng)用程序的請(qǐng)求和響應(yīng)。要使用Burp Suite攔截站點(diǎn)請(qǐng)求有兩個(gè)方案。我會(huì)傾向選用方案二,因?yàn)樗粫?huì)影響本地電腦代理配置。 安裝Burp Suite:首先,您需要在您的計(jì)算機(jī)上安裝Burp Suite社區(qū)版本,可以訪問(wèn)h

    2024年01月18日
    瀏覽(23)
  • 使用Postman攔截瀏覽器請(qǐng)求

    使用Postman攔截瀏覽器請(qǐng)求

    項(xiàng)目上線之后,難免會(huì)有BUG。在出現(xiàn)問(wèn)題的時(shí)候,我們可能需要獲取前端頁(yè)面發(fā)送請(qǐng)求的數(shù)據(jù),然后在測(cè)試環(huán)境發(fā)送相同的數(shù)據(jù)將問(wèn)題復(fù)現(xiàn)。手動(dòng)構(gòu)建數(shù)據(jù)是挺麻煩的一件事,所以我們可以借助Postman在瀏覽器上的插件幫助攔截請(qǐng)求,獲取發(fā)送的數(shù)據(jù)。 既然是基于Postman進(jìn)行操

    2024年02月15日
    瀏覽(21)
  • 登錄用戶信息獲取 網(wǎng)關(guān)+攔截器+feign請(qǐng)求添加請(qǐng)求頭

    登錄用戶信息獲取 網(wǎng)關(guān)+攔截器+feign請(qǐng)求添加請(qǐng)求頭

    給所有請(qǐng)求添加用戶身份 網(wǎng)關(guān)已經(jīng)給所有請(qǐng)求添加了用戶身份,也就是authorization頭信息。 ? 創(chuàng)建ThreadLocal工具類 : 創(chuàng)建攔截器:? 將攔截器注冊(cè)到SpringMvc,讓它生效: ?將以上代碼(攔截器,config,utils) 放到哪個(gè)微服務(wù)中,哪個(gè)微服務(wù)/**路徑就會(huì)有攔截功能 沒(méi)有用戶信息的請(qǐng)求將會(huì)

    2024年02月09日
    瀏覽(19)
  • mitmproxy 抓包神器-4.攔截請(qǐng)求實(shí)現(xiàn)篡改請(qǐng)求和返回?cái)?shù)據(jù)

    mitmproxy 抓包神器-4.攔截請(qǐng)求實(shí)現(xiàn)篡改請(qǐng)求和返回?cái)?shù)據(jù)

    fiddler 工具有個(gè)打斷點(diǎn)功能非常實(shí)用,可以實(shí)現(xiàn)攔截請(qǐng)求,篡改請(qǐng)求和返回的數(shù)據(jù)。 mitmproxy 可以用python代碼寫(xiě)插件的方式實(shí)現(xiàn)攔截請(qǐng)求,篡改請(qǐng)求和返回?cái)?shù)據(jù)。 before response:這個(gè)是打在request請(qǐng)求的時(shí)候,未到達(dá)服務(wù)器之前 after response:也就是服務(wù)器響應(yīng)之后,在Fiddler將響應(yīng)

    2024年02月11日
    瀏覽(19)

覺(jué)得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包