javascript - 如何拦截包括表单提交在内的所有http请求

标签 javascript ajax http xmlhttprequest http-proxy

我想拦截所有从我的网页发出的 http 请求,并向请求正文添加一个参数。我的页面包含表单 - 我还想捕获表单提交。我尝试过使用 Jquery ajaxSend 和 Javascript 的 setRequestHeader,但两者都不适合我。我如何实现这一点?

谢谢

最佳答案

https://developer.mozilla.org/en/docs/Web/API/Service_Worker_API

Service workers essentially act as proxy servers that sit between web applications, and the browser and network (when available).

It takes the form of a JavaScript file that can control the web page/site it is associated with, intercepting and modifying navigation and resource requests

您通过名为 sw.js 的文件在您的应用程序代码中注册一个服务 worker :

if ('serviceWorker' in navigator) {
  window.addEventListener('load', function() {
    navigator.serviceWorker.register('sw.js').then(function(registration) {
      console.log('Service worker registered with scope: ', registration.scope);
    }, function(err) {
      console.log('ServiceWorker registration failed: ', err);
    });
  });
}

并且在 sw.js 文件(实际的服务 worker 代码)中:为了拦截请求,您将 fetch 事件监听器附加到调用respondWith() 方法并对事件对象中的 .request 成员做一些事情:

self.addEventListener('fetch', function(event) {
  event.respondWith(
    // intercept requests by handling event.request here
  );
});

一个简单的 service worker 只是不加改动地传递请求,如下所示:

self.addEventListener('fetch', function(event) {
  event.respondWith(
    fetch(event.request)
  );
});

要向请求正文添加参数,您需要:

  1. 序列化请求。
  2. 修改该序列化请求。
  3. 反序列化修改后的请求以创建新请求。
  4. 使用新请求调用 fetch(…)

所以,一个 service worker 做所有的事情看起来像这样(未经测试):

self.addEventListener('fetch', function(event) {
  event.respondWith(
    fetchWithParamAddedToRequestBody(event.request)
  );
});
function fetchWithParamAddedToRequestBody(request) {
  serialize(request).then(function(serialized) {
    // modify serialized.body here to add your request parameter
    deserialize(serialized).then(function(request) {
      return fetch(request);
    });
  }); // fixed this
}
function serialize(request) {
  var headers = {};
  for (var entry of request.headers.entries()) {
    headers[entry[0]] = entry[1];
  }
  var serialized = {
    url: request.url,
    headers: headers,
    method: request.method,
    mode: request.mode,
    credentials: request.credentials,
    cache: request.cache,
    redirect: request.redirect,
    referrer: request.referrer
  };  
  if (request.method !== 'GET' && request.method !== 'HEAD') {
    return request.clone().text().then(function(body) {
      serialized.body = body;
      return Promise.resolve(serialized);
    });
  }
  return Promise.resolve(serialized);
}
function deserialize(data) {
  return Promise.resolve(new Request(data.url, data));
}

注意: https://serviceworke.rs/request-deferrer_service-worker_doc.html , 来自 Service Worker Cookbook 的页面, 是我从 https://stackoverflow.com/questions/35420980/how-to-alter-the-headers-of-a-request/35421644#35421644—and 处的答案中提取 serialize(...) 代码/方法的地方值得一看,因为那里的代码有详细的注释来解释它在做什么

关于javascript - 如何拦截包括表单提交在内的所有http请求,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43813770/

相关文章:

rest - 为什么 google-oauth API 需要重定向 URL?

向服务器发送 avro/bytes POST 请求的 java 示例

javascript - 如何将创建的范围连接到文本区域元素的值?

javascript - AngularJS 中 $interpolate 内字符串的转义字符是什么?

javascript - js 无法在 bs3 ajax 模式中工作

javascript - 如何使用 XMLHttpRequest() 正确循环 HTTP 请求?

Jquery Ajax请求不发送Post数据

javascript - 简单的 <script> 标签 - Access-Control-Allow-Origin 不允许 Origin null

javascript动态填充关联数组并获取值

java - Tomcat 7 中 SIP Servlet 的异步请求性能