XMLHttpRequest interception - xmlhttprequest

I want that when some XMLHttpRequest at 'https://myurl.com' be send, isntantly returns status code 200 and myOwnResponse at response body, I don't want that the request go to the server, the reason is that the server response is very slow, and I want to increase the performance.
I want something like tweak: mock and modify HTTP requests, how can I do that?
var _open = XMLHttpRequest.prototype.open;
window.XMLHttpRequest.prototype.open = function (method, URL) {
const myUrl = 'https://myurl.com'
if(method === 'GET' && URL === myUrl) {
const myOwnResponse = {'myResponse': true}
return myOwnResponse
} else {
return _open.apply(this, arguments);
}
};

Related

Cloudflare worker scheduled response API KV

So previously I tried to store KV when CRON was processed and it works.
Now I tried to store KV based on API responses, and tried the following: https://gist.github.com/viggy28/522c4ed05e2bec051d3838ebaff27258 and Forward body from request to another url for Scheduled (CRON workers) but doesn't seems to work.
What I attempt to do is save response in KV when CRON triggers for access_token and use it in front-end code later on.
Attached is my current attempt:
addEventListener("scheduled", (event) => {
console.log("cron trigger processed..", event);
event.waitUntil(handleRequest());
});
async function handleRequest() {
const url = "<request_url>";
const body = { <credential> };
const init = {
body: JSON.stringify(body),
method: "POST",
headers: {
"content-type": "application/json;charset=UTF-8"
}
};
const response = await fetch(url, init);
const results = await gatherResponse(response);
//#ts-ignore
AUTH.put("attempt1", results);
//#ts-ignore
AUTH.put("attempt2", new Response(results, init));
return new Response(results, init);
}
/**
* gatherResponse awaits and returns a response body as a string.
* Use await gatherResponse(..) in an async function to get the response body
* #param {Response} response
*/
async function gatherResponse(response) {
const { headers } = response
const contentType = headers.get("content-type") || ""
if (contentType.includes("application/json")) {
return JSON.stringify(await response.json())
}
else if (contentType.includes("application/text")) {
return await response.text()
}
else if (contentType.includes("text/html")) {
return await response.text()
}
else {
return await response.text()
}
}
Both attempt doesn't seems to work (KV not saved):
//#ts-ignore
AUTH.put("attempt1", results);
//#ts-ignore
AUTH.put("attempt2", new Response(results, init));
Is there anything I'm missing?
The calls to NAMESPACE.put() return a Promise that should be awaited - I'd assume that since handleRequest() can return before those are completed (since you're missing the await), they're just being cancelled.
https://developers.cloudflare.com/workers/runtime-apis/kv/#writing-key-value-pairs

Angular 10 get webservice status with Await?

Just before login in the user, I need to test if the WebServce respond then if the system is in maintenance. On the WebService part (core3 .net) I got 2 functions:
HeartBeat that return: return Ok("OK");
MaintenanceInfo that return Return OK("No");
I display in real time the result of the 2 tests and if no problems, I display the login panel.
I need to do these tests in sequence, I was thinking doing it with await operator.
I got a TestHelperServie class with 2 functions that return bool. But I can't find how to pass from a HTTP subscribe function to a bool result. With true if I got the OK response and false if I got a timeout or another fail HTTP.
For now I do this:
async TestHeartBeat()
{
let Response:Boolean = false;
const headers = new HttpHeaders()
.set('Content-Type','application/json');
const options = {
headers: headers,
observe: "response" as const,
responseType: "json" as const
};
await this.http.get(`${environment.apiUrl}/TestController/HeartBeat`, options)
.subscribe(res=>{
Response = true;
},
error=>{
Response = false;
})
return Respone;
}
But the function does not wait for the http response.
How can I fix this?
Sorry for my newbies question, but I came from the c# world and we use await/async a lot. I don't think I can do that the same way in angular 10.
You can not await on Observables, you have to convert it to promise using toPromise()
return await this.http.get(....).toPromise().then(res=> Response = true).catch(err => Response = false);
Use rxjs pipe, map and catchError.
async TestHeartBeat()
{
const headers = new HttpHeaders()
.set('Content-Type','application/json');
const options = {
headers: headers,
observe: "response" as const,
responseType: "json" as const
};
return await this.http.get(`${environment.apiUrl}/TestController/HeartBeat`, options)
.pipe(
map(res => true),
catchError(error => false)
).toPromise();
}
Now you can call it like the following:
if (await TestHeartBeat()) {
// Display your panel
} else {
// Service is in maintenance
}

Testcafe multiple requests to endpoint synchronously not working

Currently I am setting up testcafe and have hit a hurdle when making a request to the same endpoint.
This is an authentication request. The steps are currently:
Initial request is sent to server which responds with a body. This is awaited
Once step is retrieved from step 1 this is mutated and sent back to the server.
We then the same endpoint and pass in the body generated in step 2
But I am having issues in the testcafe tests as it always using the first request and returns that twice.
I have referred to this issue on testcafe https://github.com/DevExpress/testcafe/issues/2477 however this did not work.
const mock = (mockResponse, status) => {
return RequestMock()
.onRequestTo(/\/apitest\/authenticate\)
.respond(mockResponse, status, {
"Access-Control-Allow-Origin": "http://localhost:3000",
"Access-Control-Allow-Credentials": "true"
});
};
const mock1 = mock(RESPONSE1, 200);
const mock2 = mock(RESPONSE2, 200);
test.requestHooks(mock1)(
"Should redirect to error if user has been suspended after submitting",
async t => {
const usernameInput = Selector("#username");
const mobileDigitOne = Selector("#mobile-digit-0");
const mobileDigitTwo = Selector("#mobile-digit-1");
const mobileDigitThree = Selector("#mobile-digit-2");
const submitButton = Selector("#submit-button");
await t
.typeText(usernameInput, "username123456")
.click(digits)
.typeText(digits, "123456")
.click(submitButton);
await t.removeRequestHooks(mock1);
await t.addRequestHooks(mock2);
Any ideas on how to request same endpoint multiple times?
You can distinguish different requests to the same endpoint using the request body. You can pass different kinds of filter to the mock's onRequestTo method, including a predicate function. Refer to the Filter with a Predicate article for more details.
Thus, you can use a single mock for both requests, like this:
function isTheSecondRequest(requestBody) {
// This should return `true` for the mutated request body
// and `false` for the original one.
//
// For example:
return requestBody.indexOf('{ foo: bar }') !== -1;
}
const mock = RequstMock()
.onRequestTo(request => {
request.url === '/apitest/authenticate' &&
!isTheSecondRequest(request.body)
})
.respond(RESPONSE1, 200, HEADERS)
.onRequestTo(request => {
request.url === '/apitest/authenticate' &&
isTheSecondRequest(request.body)
})
.respond(RESPONSE2, 200, HEADERS);

Xhttp request always returns a 0 response code. - While making a post request using form data

I am trying to upload an array of images using form data and xhttp.
Client : React Native - Both platforms
Server : Node running on GCP
Images go into s3.
Problem : Images are uploaded into s3. And when i look at my server logs i see the server is sending 200.
But, client is always receiving response code 0.
And also xhttp goes from state 1 -> 4.
We have added CORS on both ends so that might not be an issue.
I have accept and content headers. But, no idea what's going wrong.
Any help is appreciated.
React-Native Client:
upload()
{
let url = "MYAPIGOESHERE"
let uploadBody = new FormData()
let imagesUpload = []
imagesUpload.push({type:'image/jpg',uri:this.state.coverImage[0].uri,name:"cover"})
uploadBody.append('photos',{uri:this.state.coverImage[0].uri, type:'image/jpg', name:"cover"})
uploadBody.append('duration',this.state.duration)
var xhttp = new XMLHttpRequest()
xhttp.onreadystatechange = function() {
console.log(this.readyState+" "+this.statusText)
if (this.readyState === 4) {
alert(this.status)
if (this.status === 200) {
console.log(this.responseText);
} else {
console.log(this);
}
}
if(this.readyState === 3)
{
console.log("Inside 3")
}
if(this.readyState === 2)
{
console.log("Inside 2")
}
};
xhttp.open("POST", url)
xhttp.setRequestHeader('Accept', 'application/json');
xhttp.setRequestHeader('Access-Control-Allow-Origin', '*');
xhttp.responseType = 'json'
xhttp.send(uploadBody)
}

Disable concurrent or simultaneous HTTP requests AXIOS

We are having a trouble with our refresh authentication token flow, where if multiple requests are made with the same expired access token at the same time, all of them would make backend to refresh the token and would have different refreshed tokens in their responses. Now when the next request is made, the refresh token of the last response would be used which may or may not be latest.
One solution to this problem is to have UI (which is using axios in vue) send only one request at a time. So if a token is refreshed, the following request would have the latest token.
Hence I am wondering if axios has a default option to disable simultaneous requests as I couldn't find anything online about it. Another solution would be to maintain a queue of requests, where each request is only sent when a response (either success or fail) is received for the previous request(manual option). I understand that this might decrease the performance as it may seem in the UI, but it would also take the load off backend.
One possible solution I found here is to use interceptor:
let isRefreshing = false;
let refreshSubscribers = [];
const instance = axios.create({
baseURL: Config.API_URL,
});
instance.interceptors.response.use(response => {
return response;
}, error => {
const { config, response: { status } } = error;
const originalRequest = config;
if (status === 498) { //or 401
if (!isRefreshing) {
isRefreshing = true;
refreshAccessToken()
.then(newToken => {
isRefreshing = false;
onRrefreshed(newToken);
});
}
const retryOrigReq = new Promise((resolve, reject) => {
subscribeTokenRefresh(token => {
// replace the expired token and retry
originalRequest.headers['Authorization'] = 'Bearer ' + token;
resolve(axios(originalRequest));
});
});
return retryOrigReq;
} else {
return Promise.reject(error);
}
});
subscribeTokenRefresh(cb) {
refreshSubscribers.push(cb);
}
onRrefreshed(token) {
refreshSubscribers.map(cb => cb(token));
}