Reputation: 1675
I am using a 3rd party JavaScript API library delivered through a CDN. The library exposes methods that behind the scenes does an HTTP request that I don't have control over. Is it possible to intercept the HTTP request and alter the response on the client.
For example, let's say the library is a JavaScript math library delivered through a CDN that exposes the variable mathcdn
with some math functions like add
:
<script src="math.cdn.com"></script>
<script>
var sum = mathcdn.add([4, 4])
</script>
If behind the scenes, the mathcdn.add
method did a HTTP request to a math API to actually compute the sum of the two numbers, could I tell the request to just mock a response?
For example, when the library wants to call api.com/add?nums[4,5]
, don't actually send the request, but instead mock a response of {sum: 9}
.
I've seen this when writing tests with mocks
, but I need to do this on the client.
Upvotes: 0
Views: 660
Reputation: 445
As far as I know, extensions' webRequest APIs
do allow you to intercept HTTP requests. But I don't think you can do that with normal javascript APIs, since it will cause security issues.
However, you can still accomplish a similar result with some workarounds. For instance, hijack window.fetch()
in the first place.
<script>
// In case you need to use it again.
const originalFetch = window.fetch
window.fetch = function(resource, init) {
// Let some requests act as usual,
// e.g., requests from other 3rd-party libraries.
if (...) return originalFetch(resource, init)
// Extract the information you need,
// e.g., query string in the url,
// and create the corresponding result.
const result = ...
// Wrap the result in a Response object,
// which is how the original fetch returns it.
// So it won't break the library's following code.
return new Response(result)
}
</script>
<script src="math.cdn.com"></script>
XMLHttpRequest
.async
attribute, because the execution order will become unpredictable, and the library may store a reference to window.fetch()
before you replace it.Upvotes: 1