[C#][.NET Core] 試著在 Jint 模擬做到 XMLHttpRequest (XHR) 的效果

2022-02-22

之前寫過關於 Jint 的文章可以參考這一篇 試著用 C# 透過 Jint 執行 Javascript ,混和執行

今天 主要是來說 Jint 模擬做到 XMLHttpRequest (XHR) 的效果,為何要這樣做,簡單的就是人做專案身不由己

簡單的來說一下邏輯,基本上就是利用可以混和執行的特性,自己先去封裝 RestSharp ,之後再讓 Jint 來達到這個效果

其實說穿了大概就是這樣,因為我之前有簡單封裝了一個版本這邊就不贅述,直接上 code.


1. 先 nuget RestSharp(160.12)  ,因為後面 170 好像有改版,我程式是之前寫的,好像 170 會有點語法上不一樣,等有時間我再來補坑

當然還有 Jint 


2. 加入程式碼 RestSharpJintAgent.cs

public class RestSharpJintAgent { public class RestSharpAgentSendResult { public string Code { get; set; } public string Result { get; set; } public string Message { get; set; } public string Status { get; set; } } public class RestSharpAgentDetail { public RestSharp.RestClient Client; public RestSharp.RestRequest Request; public RestSharpAgentDetail AddContent(dynamic src) { if (Client == null) return this; if (Request == null) return this; Request.AddJsonBody(src); return this; } public RestSharpAgentDetail AddQS(string key, string value) { if (Client == null) return this; if (Request == null) return this; Request.AddParameter(key, value, ParameterType.QueryString); return this; } public RestSharpAgentDetail AddHeader(string key, string value) { if (Client == null) return this; if (Request == null) return this; if (string.IsNullOrEmpty(key)) return this; Request.AddOrUpdateHeader(key, value); return this; } public RestSharpAgentSendResult Send() { var res = new RestSharpAgentSendResult { Message = "Client is Null", Status = "ERROR" }; if (Client == null) { return res; } try { var result = Client.ExecuteAsync(Request).Result; res.Code = ((int)(result.StatusCode)).ToString(); res.Status = "SUCCESS"; res.Message = ""; res.Result = result.Content; return res; } catch (Exception ex) { res.Status = "ERROR"; res.Message = ex.StackTrace + "," + ex.Message; return res; } } } public class RestSharpAgent4 { public static RestSharpAgentDetail GetAgent(string baseUrl, string resource, string method) { var res = new RestSharpAgentDetail(); res.Client = new RestSharp.RestClient(baseUrl); res.Request = new RestSharp.RestRequest(); var req = new RestSharp.RestRequest(); if (method.ToUpper() == "POST") { res.Request.Method = RestSharp.Method.POST; } if (method.ToUpper() == "GET") { res.Request.Method = RestSharp.Method.GET; } if (method.ToUpper() == "PUT") { res.Request.Method = RestSharp.Method.PUT; } if (method.ToUpper() == "DELETE") { res.Request.Method = RestSharp.Method.DELETE; } res.Request.Resource = resource; res.Request.RequestFormat = RestSharp.DataFormat.Json; return res; } } }


3. 這邊我測試的是 postman 的 echo 機器

GET:  https://postman-echo.com/get?A=當麻許&B=3.1415926

Result:

{"args":{"A":"當麻許","B":"3.1415926"},"headers": {"x-forwarded-proto":"https","x-forwarded-port":"443", "host":"postman-echo.com", "x-amzn-trace-id":"Root=1-62144f0a-630ee3c662ec62d753219a0e", "sec-ch-ua":"\" Not A;Brand\";v=\"99\", \"Chromium\";v=\"98\", \"Google Chrome\";v=\"98\"", "sec-ch-ua-mobile":"?0","sec-ch-ua-platform":"\"Windows\"", "upgrade-insecure-requests":"1", "user-agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.102 Safari/537.36", "accept":"text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9", "sec-fetch-site":"none", "sec-fetch-mode":"navigate", "sec-fetch-user":"?1","sec-fetch-dest":"document","accept-encoding":"gzip, deflate, br", "accept-language":"zh-TW,zh;q=0.9,en-US;q=0.8,en;q=0.7", "cookie":"sails.sid=s%3AoaRFpwLIY1rtu3e5NuUOJ0qh1noQfVXb.Lovie0%2FB2l6%2F%2B6tWBztevTXQIYsdHZB%2BZze5v10yf4k"} ,"url":"https://postman-echo.com/get?A=%E7%95%B6%E9%BA%BB%E8%A8%B1&B=3.1415926"}


POST: 

curl --location --request POST 'https://postman-echo.com/post' \
--form 'A="當麻許"' \
--form 'B=3.1415926'


Result:

{"args":{"A":"許當麻","B":"3.14"}, "data":"\"\"","files":{}, "form":{}, "headers":{"x-forwarded-proto":"https", "x-forwarded-port":"443", "host":"postman-echo.com", "x-amzn-trace-id":"Root=1-6214505c-2ef95dfa20a02ceb0cbcdce8", "content-length":"2","auth":"", "accept":"application/json, text/json, text/x-json, text/javascript, application/xml, text/xml", "user-agent":"RestSharp/106.15.0.0","accept-encoding":"gzip, deflate","content-type":"application/json"}, "json":null,"url":"https://postman-echo.com/post?A=%E8%A8%B1%E7%95%B6%E9%BA%BB&B=3.14"}


4.再來就是 Jint 呼叫的部分,這邊我封裝叫做 WebClient 畢竟我就是很古典 :P

var engine = new Jint.Engine(); engine.SetValue("WebClient", new RestSharpJintAgent.RestSharpAgent4()); var jsCode = @" function Main(){ var obj=new Object(); obj.A='許當麻'; obj.B=123.456; //https://postman-echo.com/get?foo1=bar1&foo2=bar2 //Get : // var res = WebClient.GetAgent('https://postman-echo.com', 'get', 'get') var res = WebClient.GetAgent('https://postman-echo.com', 'post', 'post') .AddHeader('AUTH', '') .AddContent('') .AddQS('A','許當麻').AddQS('B',3.1415926).Send(); if (res.Status == 'SUCCESS') { if (res.Code == '200') { //return res.Result; var result=JSON.parse(res.Result); return result.args.A+', '+ result.args.B; // result : 當麻許,3.1415926 } } } "; engine.Execute(jsCode); var result = engine.Execute("Main()").GetCompletionValue(); Console.WriteLine(result);


如果不符合需要的可能需要再自行改寫了


reference:

https://documenter.getpostman.com/view/5025623/SWTG5aqV


當麻許的碎念筆記 2014 | Donma Hsu Design.