Skip to content

Commit

Permalink
repo
Browse files Browse the repository at this point in the history
  • Loading branch information
fbarbare committed Mar 1, 2017
1 parent 898f054 commit f0dffcf
Show file tree
Hide file tree
Showing 6 changed files with 92 additions and 147 deletions.
3 changes: 3 additions & 0 deletions .babelrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"presets": ["es2015"]
}
7 changes: 2 additions & 5 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
*~
**~
build
.DS_Store
node_modules
.idea
*.iml
script.js
4 changes: 0 additions & 4 deletions .npmignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,2 @@
.DS_Store
*.log
node_modules
build
*.node
components
66 changes: 25 additions & 41 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,59 +1,43 @@
ajax-interceptor
================
xhr-intercept
-------------

This permits to wire some request and response hooks on any Ajax calls.

I find this handy, for exemple, to handle user session expiration and redirect the user to the login page whenever an Ajax call fails with an auth failure.

Install
==============
-------

Install it!
```
npm install ajax-interceptor --save
```

Use it! (with **Browserify**)
```javascript
var AjaxInterceptor = require("ajax-interceptor");
npm i -S xhr-intercept
```

No other support for now, but feel free to contribute.


API
===============
---

```javascript
// Setup some callbacks
AjaxInterceptor.addRequestCallback(function(xhr) {
console.debug("request",xhr);
});
AjaxInterceptor.addResponseCallback(function(xhr) {
console.debug("response",xhr);
});

// Will proxify XHR to fire the above callbacks
AjaxInterceptor.wire();

// Do some requests
// ................

// Will restore XHR and not fire anymore the callbacks
AjaxInterceptor.unwire();
```
import XhrIntercept from 'xhr-intercept';

You can add and remove callbacks dynamically while the interceptor is wired.
function onRequest(xhr, args) {
console.debug('request', xhr);

// Return false to cancel the request
return false;
}

function onResponse(xhr) {
console.debug('request', xhr);
}

Alternatives
===================
// Add a callback on request or response
XhrIntercept.addRequestCallback(onRequest);
XhrIntercept.addResponseCallback(onResponse);

If you just want to be able to intercept JQuery $.ajax() calls, [Global Ajax Event Handlers](http://api.jquery.com/category/ajax/global-ajax-event-handlers/) also work.
// Starting intercepting requests
XhrIntercept.wire();

License
===================

MIT
// Remove a callback on request or response
XhrIntercept.removeRequestCallback(onRequest);
XhrIntercept.removeResponseCallback(onResponse);

// Stopping intercepting requests
XhrIntercept.unwire();
```
111 changes: 32 additions & 79 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,99 +1,52 @@
'use strict';

var COMPLETED_READY_STATE = 4;

var RealXHRSend = XMLHttpRequest.prototype.send;

var requestCallbacks = [];
var responseCallbacks = [];

const XMLHttpRequestSend = XMLHttpRequest.prototype.send;

var reqCallbacks = [];
var resCallbacks = [];
var wired = false;

export function isWired() {
return wired;
};

function arrayRemove(array,item) {
var index = array.indexOf(item);
if (index > -1) {
array.splice(index, 1);
} else {
throw new Error("Could not remove " + item + " from array");
}
}


function fireCallbacks(callbacks,xhr) {
for( var i = 0; i < callbacks.length; i++ ) {
callbacks[i](xhr);
}
}


exports.addRequestCallback = function(callback) {
requestCallbacks.push(callback);
export function addRequestCallback(callback) {
reqCallbacks.push(callback);
};
exports.removeRequestCallback = function(callback) {
arrayRemove(requestCallbacks,callback);
export function addResponseCallback(callback) {
resCallbacks.push(callback);
};


exports.addResponseCallback = function(callback) {
responseCallbacks.push(callback);
export function removeRequestCallback(callback) {
reqCallbacks = reqCallbacks.filter(item => item !== callback);
};
exports.removeResponseCallback = function(callback) {
arrayRemove(responseCallbacks,callback);
export function removeResponseCallback(callback) {
resCallbacks = resCallbacks.filter(item => item !== callback);
};

export function wire() {
if (wired) { throw new Error('Ajax interceptor already wired'); }

XMLHttpRequest.prototype.send = function() {
var reqCallbacksRes = reqCallbacks.map(callback => callback(this, arguments));
var onreadystatechange = this.onreadystatechange;

function fireResponseCallbacksIfCompleted(xhr) {
if( xhr.readyState === COMPLETED_READY_STATE ) {
fireCallbacks(responseCallbacks,xhr);
}
}
this.onreadystatechange = () => {
resCallbacks.forEach(callback => {callback(this)});
onreadystatechange(this);
};

function proxifyOnReadyStateChange(xhr) {
var realOnReadyStateChange = xhr.onreadystatechange;
if ( realOnReadyStateChange ) {
xhr.onreadystatechange = function() {
fireResponseCallbacksIfCompleted(xhr);
realOnReadyStateChange();
};
if (reqCallbacksRes.indexOf(false) === -1) {
XMLHttpRequestSend.apply(this, arguments);
}
}


exports.isWired = function() {
return wired;
}

exports.wire = function() {
if ( wired ) throw new Error("Ajax interceptor already wired");
};

// Override send method of all XHR requests
XMLHttpRequest.prototype.send = function() {

// Fire request callbacks before sending the request
fireCallbacks(requestCallbacks,this);

// Wire response callbacks
if( this.addEventListener ) {
var self = this;
this.addEventListener("readystatechange", function() {
fireResponseCallbacksIfCompleted(self);
}, false);
}
else {
proxifyOnReadyStateChange(this);
}

RealXHRSend.apply(this, arguments);
};
wired = true;
wired = true;
};


exports.unwire = function() {
if ( !wired ) throw new Error("Ajax interceptor not currently wired");
XMLHttpRequest.prototype.send = RealXHRSend;
wired = false;
export function unwire() {
if (!wired) { throw new Error('Ajax interceptor not currently wired'); }

XMLHttpRequest.prototype.send = XMLHttpRequestSend;
wired = false;
};
48 changes: 30 additions & 18 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,20 +1,32 @@
{
"name": "ajax-interceptor",
"version": "1.0.1",
"description": "Permits to intercept Ajax calls. Useful to detect disconnected user or things like that",
"keywords": [
"xhr",
"ajax",
"aop",
"proxy",
"interceptor"
],
"author": "Sebastien Lorber",
"homepage": "https://github.com/slorber/ajax-interceptor",
"bugs": "https://github.com/slorber/ajax-interceptor/issues",
"license": "MIT",
"repository": {
"type": "git",
"url": "https://github.com/slorber/ajax-interceptor"
}
"name": "xhr-intercept",
"version": "0.1.1",
"description": "Allows you to intercept XHR requests. Useful to detect disconnected users, delaying calls while reconnecting them, things like that.",
"keywords": [
"xhr",
"http",
"request",
"ajax",
"aop",
"proxy",
"intercept",
"interceptor"
],
"author": "Florian Barbare",
"homepage": "https://github.com/fbarbare/xhr-intercept",
"bugs": "https://github.com/fbarbare/xhr-intercept/issues",
"license": "MIT",
"repository": {
"type": "git",
"url": "https://github.com/fbarbare/xhr-intercept"
},
"main": "./script.js",
"scripts": {
"prepublish": "babel index.js --out-file script.js"
},
"devDependencies": {
"babel": "^6.23.0",
"babel-cli": "^6.23.0",
"babel-preset-es2015": "^6.22.0"
}
}

0 comments on commit f0dffcf

Please sign in to comment.