jameslnewell / xhr-mock

Utility for mocking XMLHttpRequest.
196 stars 48 forks source link

proxy.browser does not support sync xhr #48

Closed rajsite closed 1 year ago

rajsite commented 6 years ago

I think the behavior I am seeing is that when proxy.browser is used to proxy synchronous requests I get an error because, the proxy seems to always returns a Promise:

https://github.com/jameslnewell/xhr-mock/blob/056283d9e184551fb4df88c9c44e34c7624a45fd/packages/xhr-mock/src/proxy.browser.ts#L21

Which fails on this check sendSync:

https://github.com/jameslnewell/xhr-mock/blob/f761cde79748561ea8288a1974c5c9dec0499a41/packages/xhr-mock/src/MockXMLHttpRequest.ts#L267

jameslnewell commented 6 years ago

Thanks @rajsite. Yeah sorry, I don't use async=false so I haven't implemented it yet. Want to submit a PR for supporting both sync and async?

rajsite commented 6 years ago

Hey @jameslnewell thanks for letting me know the state of the repo!

For the project I'm experimenting with I was leaning very heavily on the proxy feature. I needed synx xhr, timeouts, aborts, responseType arraybuffer, support for arraybuffer bodies, and probably some more to proxy correctly. I wasn't able to get to a point where I can test all of those behaviors in XHRMock but from the source it seems like a few others are probably missing besides sync xhr.

I do like the url matching ability of xhrmock but for the moment I am experimenting with xhook which seems to be proxying all of the above well so far https://github.com/jpillora/xhook/

It's CoffeeScript-based, not TypeScript-based, but it could be leveraged by XHRMock to flesh out the proxy behavior.

jameslnewell commented 6 years ago

No worries!

Here's what should work:

Implementing a sync proxy should be as simple as getting rid of the promise e.g:

export default function(
  req: MockRequest,
  res: MockResponse
): MockResponse {
  const xhr: XMLHttpRequest = new XHRMock.RealXMLHttpRequest();

  // TODO: reject with the correct type of error
  xhr.onerror = event => {throw event};

  xhr.onloadend = () => {
    res
      .status(xhr.status)
      .reason(xhr.statusText)
      .headers(parseHeaders(xhr.getAllResponseHeaders()))
      .body(xhr.responseText);
  };

  xhr.open(req.method(), req.url().toString());

  const headers = req.headers();
  Object.keys(headers).forEach(name => {
    const value = headers[name];
    xhr.setRequestHeader(name, value);
  });

   xhr.send(req.body());

  return res;
}

Yeah that lib looks nice too.

rajsite commented 1 year ago

Sync XHR has long since been deprecated and my usages were cleaned up. Doesn't seem like others have asked about it so probably fine to close out for now 👍