@uipath/apps-communication-driver
v2.0.8
Published
A lightweight and secure communication library for cross-window messaging between parent windows and iframes.
Downloads
38
Maintainers
Keywords
Readme
UiPath Communication Driver
A lightweight and secure communication library for cross-window messaging between parent windows and iframes.
Features
- Secure cross-window communication with origin validation
- Promise-based handshake mechanism with configurable timeout
- Event-based message passing
- Channel caching for improved performance
- TypeScript support
Installation
npm install @uipath/apps-communication-driver
# or
yarn add @uipath/apps-communication-driverUsage
Parent Window Integration
Here's how to integrate the communication-driver in your parent window:
import { handshake } from '@uipath/apps-communication-driver;
// Create an iframe element
const iframe = document.createElement('iframe');
iframe.src = 'https://your-child-origin.com';
document.body.appendChild(iframe);
// Initialize communication
const { channel } = await handshake({
targetOrigin: 'https://your-child-origin.com',
iframe: iframe,
timeout: 10000 // Optional: Set a custom timeout in milliseconds (default: 5000ms)
});
// Listen for messages from the child
channel.on('someEvent', (data) => {
console.log('Received from child:', data);
});
// Send messages to the child
channel.send('someEvent', { message: 'Hello from parent!' });Reference Implementation Example
Here's a complete example of a parent window implementation:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Parent Window</title>
</head>
<body>
<h1>Parent Window</h1>
<div style="display: flex; gap: 16px; margin-bottom: 16px;">
<input type="text" id="messageInput" placeholder="Enter your message">
<input type="text" id="eventName" placeholder="Enter event name">
<button onclick="sendMessage()">Submit</button>
</div>
<iframe id="app-frame"
src="https://your-child-origin.com"
width="100%" height="800">
</iframe>
<script>
var channel;
function sendMessage() {
const messageInput = document.getElementById('messageInput');
const eventName = document.getElementById('eventName').value;
const message = messageInput.value;
if (message.trim()) {
channel.send(`${eventName}`, { message });
messageInput.value = '';
}
}
</script>
<script type="module">
import { handshake } from './driver.js';
try {
const iframe = document.getElementById("app-frame");
const { channel: localChannel } = await handshake({
targetOrigin: "https://your-child-origin.com",
iframe,
targetWindow: iframe.contentWindow,
timeout: 10000 // Optional: Set a custom timeout in milliseconds
});
channel = localChannel;
// Listen for messages from the child
channel.on("EVENT_FROM_APP", (data) => {
console.log("Received from App:", data);
});
} catch (error) {
console.error('Communication error:', error);
}
</script>
</body>
</html>This example demonstrates:
- Setting up an iframe with a specific source
- Creating input fields for message and event name
- Implementing a send message function
- Properly initializing the communication channel with error handling
- Setting up event listeners for receiving messages
Child Window (iframe) Integration
In your child window or iframe:
import { handshake } from '@uipath/apps-communication-driver';
// Initialize communication with parent
const { channel } = await handshake({
targetOrigin: 'https://your-parent-origin.com',
timeout: 10000 // Optional: Set a custom timeout in milliseconds
});
// Listen for messages from the parent
channel.on('someEvent', (data) => {
console.log('Received from parent:', data);
});
// Send messages to the parent
channel.send('someEvent', { message: 'Hello from parent!' });API Reference
Handshake Options
interface HandshakeOptions {
targetOrigin: string; // The expected origin for messages
targetWindow?: Window; // The window to communicate with (optional)
iframe?: HTMLIFrameElement; // Optional iframe instance for communication
timeout?: number; // Optional timeout in milliseconds (default: 5000ms)
}Channel Interface
interface Channel {
send: (event: string, data: any) => void;
on: (event: string, callback: (data: any) => void) => void;
}Security Considerations
- Always specify the correct
targetOriginto ensure messages are only accepted from trusted sources - The library automatically validates message origins
- Messages are only processed if they match the expected origin
Best Practices
Error Handling: Always wrap the handshake in a try-catch block:
try { const { channel } = await handshake({ targetOrigin: 'https://your-child-origin.com', iframe: iframe, timeout: 10000 // Set an appropriate timeout for your use case }); } catch (error) { console.error('Failed to establish communication:', error); // Handle timeout errors specifically if (error.message.includes('timed out')) { console.error('Handshake timed out. The other party did not respond in time.'); } }Event Naming: Use consistent and descriptive event names across your application
Data Validation: Validate data received through the channel before processing
Cleanup: Remove event listeners when they're no longer needed:
channel.on('someEvent', null); // Remove the listenerTimeout Configuration: Set an appropriate timeout value based on your application's needs:
- For local development, shorter timeouts (1000-2000ms) can help identify issues faster
- For production, consider network latency and set timeouts accordingly (5000-10000ms)
- For high-latency environments, you may need longer timeouts
Browser Support
The library uses the standard postMessage API and is supported in all modern browsers:
- Chrome 4+
- Firefox 3+
- Safari 4+
- Edge 12+
- IE 8+
License
MIT
