Nodejs里采用flash封装的跨域要引用策略文件的问题,如何解决?各位大神帮忙看看,在下感激不尽。

Nodejs里采用flash封装的跨域要引用策略文件的问题,如何解决?各位大神帮忙看看,在下感激不尽。

flash代码:

package  
{
	import flash.display.*;
	import flash.events.*;
	import flash.net.*;
	import flash.system.*;
	import flash.text.*;
	import flash.utils.*;
	/*
	 * 
	 */
	public class Client extends Sprite {
		
		public function Client():void {
			var socket:Socket = new Socket();
			socket.addEventListener(Event.CONNECT,onEvent);//侦听连接事件
			socket.addEventListener(Event.CLOSE,onEvent);//侦听关闭事件
			socket.addEventListener(ProgressEvent.SOCKET_DATA,onEvent);//侦听数据收到事件
			socket.connect('127.0.0.1',3944);//连接服务端
		}
		public function onEvent(e:Event):void	{
			var socket:Socket = e.target as Socket;
			switch(e.type){
				case Event.CONNECT:
					trace('已连接成功');
					socket.writeUTFBytes('我是来自客户端的消息');//把字符串按照utf-8的编码发出去
					break;
				case Event.CLOSE:
					trace('服务器关闭!');
					socket.close();
					break;
				case ProgressEvent.SOCKET_DATA:
					trace('收到数据,长度'+socket.bytesAvailable);
					read(socket);
					break;
			}
		}
		public function read(socket:Socket):void	{
			var ba:ByteArray = new ByteArray();//缓冲区
			socket.readBytes(ba,0,socket.bytesAvailable);//按收到的数据长度来读
			var val:String = ba.readUTFBytes(ba.length);//安装utf-8的编码解析二进制
			trace(val);
		}
	}

}

服务端代码:

var XML =
'<?xml version="1.0"?>' +
'<!DOCTYPE cross-domain-policy SYSTEM "http://www.macromedia.com/xml/dtds/cross-domain-policy.dtd">' +
'<cross-domain-policy>' +
'<allow-access-from domain="*" to-ports="*" />' +
'</cross-domain-policy>'

var net = require('net'),
	http = require("http"),
	fs = require("fs"),
	path = require("path"),
	url = require("url");
	
var index = 0;
var server = net.createServer(
	function(socket){
		index++;
		new Client(index,socket);
});
server.listen(3944, '127.0.0.1');

console.log('服务端已开启...');

function Client(index,socket) {
    var myIndex = index;
	socket.setTimeout(1500, function() {
		console.log(socket.remoteAddress + ' 超时');
		socket.destroy();
	});
	
	socket.on('data', function(data) {
		if(data.toString()=='<policy-file-request/>\0'){
			socket.write('你好,第'+myIndex+'号客户端。我是服务端','utf-8');
			socket.write(XML);
			console.log('相等');
			console.log(data.toString());
			socket.end();
		}		
	});    
}

6 回复

针对Node.js中使用Flash进行跨域通信时需要引用策略文件的问题,可以通过在服务器端处理特定的请求来实现。这种情况下,Flash客户端会发送一个特殊的请求(<policy-file-request/>)到指定端口,以获取跨域策略文件。

解决方案

  1. 创建策略文件:首先,创建一个XML格式的策略文件,允许所有域访问你的服务器。

  2. 服务器端处理策略文件请求:在Node.js服务器上监听特定端口,并在接收到特定的策略文件请求时返回该策略文件。

示例代码

创建策略文件 crossdomain.xml

<?xml version="1.0"?>
<!DOCTYPE cross-domain-policy SYSTEM "http://www.macromedia.com/xml/dtds/cross-domain-policy.dtd">
<cross-domain-policy>
    <allow-access-from domain="*" to-ports="*" />
</cross-domain-policy>

Node.js服务器代码

const net = require('net');
const fs = require('fs');
const path = require('path');

// 读取策略文件
const policyFile = fs.readFileSync(path.join(__dirname, 'crossdomain.xml'));

// 创建TCP服务器
const server = net.createServer((socket) => {
    const data = '';

    socket.on('data', (chunk) => {
        data += chunk;

        // 检查是否为策略文件请求
        if (data.includes('<policy-file-request/>\0')) {
            console.log('收到策略文件请求');
            socket.end(policyFile);
        }
    });

    socket.on('end', () => {
        console.log('连接结束');
    });
});

server.listen(843, '127.0.0.1', () => {
    console.log('策略文件服务器已启动,监听843端口');
});

解释

  1. 策略文件crossdomain.xml 文件定义了跨域策略,允许所有域访问所有端口。

  2. 服务器代码

    • 创建一个TCP服务器,监听843端口(这是Flash策略文件请求的标准端口)。
    • 当接收到客户端的连接时,检查传入的数据是否包含 <policy-file-request/>\0 字符串。
    • 如果检测到策略文件请求,则将 crossdomain.xml 文件的内容发送回客户端并关闭连接。

通过这种方式,可以确保Flash客户端能够正确地从Node.js服务器获取跨域策略文件,从而实现跨域通信。


重复读了3次标题,惭愧啊,以我小学语文没毕业的水平,只能看懂问题是关于flash封装的跨域要引用策略文件,但是具体是什么,flash客户端发送不出?服务端接受不到?访问拒绝?flash不能解析策略文件?无解。楼下能看明白的,请告之并BS我吧。

呃,既然回帖姑且猜猜看看吧。请求既然以0结束,回复不也应该以0结束吗。

   if(data.toString()=='<policy-file-request/>\0'){
        socket.write(XML+'\0');
        console.log('相等');
        console.log(data.toString());
        socket.end();
    }  

感觉代码还算好懂… 我居然看懂了 Flash 代码, 不好意思, 楼上能不能讲解下 \0?

你能看懂楼主想问什么?好担心我的语文水平是不是又下降了。 \0是xmlsocket的结束符,c的字符串不就是以0结束吧,不加个0的话后果自负。

\0是截至符号

在Flash与Node.js通信时,Flash会尝试加载策略文件以确保安全跨域通信。该策略文件需要由服务器提供,以便Flash能够确认通信是安全的。

示例代码

服务端代码可以稍微调整一下,以正确处理策略文件请求:

var XML =
'<?xml version="1.0"?>' +
'<!DOCTYPE cross-domain-policy SYSTEM "http://www.macromedia.com/xml/dtds/cross-domain-policy.dtd">' +
'<cross-domain-policy>' +
'<allow-access-from domain="*" to-ports="*" />' +
'</cross-domain-policy>';

var net = require('net');

var server = net.createServer(function(socket) {
    if (socket.remoteAddress === '::ffff:127.0.0.1') {
        // 如果请求的是策略文件
        if (socket.read().toString() === '<policy-file-request/>\0') {
            console.log('策略文件请求');
            socket.write(XML);
            socket.end();
        } else {
            // 处理正常数据
            new Client(socket);
        }
    }
});

server.listen(3944, '127.0.0.1');

console.log('服务端已开启...');

function Client(socket) {
    socket.setTimeout(1500, function() {
        console.log(socket.remoteAddress + ' 超时');
        socket.destroy();
    });

    socket.on('data', function(data) {
        console.log('收到数据:', data.toString());
        socket.write('我是服务端,已接收消息');
    });
}

解释

  1. 服务端

    • 创建一个TCP服务器监听3944端口。
    • 当客户端连接时,检查是否是策略文件请求(<policy-file-request/>)。
    • 如果是策略文件请求,返回XML格式的策略文件,并结束连接。
    • 否则,继续处理正常的数据通信。
  2. 客户端

    • 保持不变,继续使用现有Flash代码进行通信。

这样修改后,当Flash客户端连接到服务端时,如果它发送策略文件请求,服务端将返回正确的策略文件,从而允许跨域通信。

回到顶部