情景是这样的,一个客户端,界面基于html开发,这样的页面就没有办法在java脚本中使用ajax向服务器发请求。为了解决这个问题,可以在客户端架设一个http服务器,并注册路由,某些url只需要本地服务器处理,而某些url则转发给服务器(或者都给双方一个通知)。
演示的页面:
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>world</title> </head> <body> <div> <p>local image:</p> <img src="logo_g3_not_proxy.png"></img> </div> <div> <p>remote image:</p> <img src="/logo_g3.png"></img> </div> <div> <p id="responseText"></p> </div> <p id="message"></p> <div> <p id="messageStatus"></p> <p id="messageText"></p> </div> <p id="text"></p> <script src="js/jquery.js"></script> <script> $(function($) { var request = new XMLHttpRequest(); var url = "/sunshine.txt"; request.open("GET", url, false); request.send(); if(request.status = 200) { $("#responseText").text("XMLHttpRequest rsp: " + request.responseText); } else { $("#responseText").text("XMLHttpRequest error"); } }); function showMessage(message) { $("#message").text("JSONP message: " + message); } </script> <!-- JSONP --> <script src="/js/helloMessage.js"></script> </body> </html>
本地http服务器,基于node.js,配置node-static模块:
var url = require("url"); var http = require("http"); var static = require("node-static"); var router = require("./router.js"); var port = 7000; var website = ".."; var argv = process.argv; if(argv.length > 2) { port = parseInt(argv[2]); if(argv.length > 3) { website = argv[3]; } } function httpProxy(urlObj, request, response, host, port) { var temp = url.parse(request.url, true); var opt = {}; opt.host = host; opt.port = port; opt.method = request.method; opt.path = urlObj.path; //TODO copy headers will casue exception var req = http.request(opt, function (res) { res.on("data", function (chunk) { response.write(chunk); }); res.on("end", function () { response.end(); }); }); req.end(); } // // Create a node-static server instance to serve the './public' folder // var file = new(static.Server)(website); require('http').createServer(function (request, response) { request.addListener('end', function () { var urlObj = url.parse(request.url, true); var routeResult = router.route(urlObj.path); if(!routeResult) { file.serve(request, response); } else { httpProxy(urlObj, request, response, routeResult.host, routeResult.port); if(routeResult.method == "both") { file.serve(request, response); } } }); }).listen(port); console.log("server running at " + port + " under " + website);
注册路由:
exports.route = function(path) { console.log("routing path: " + path);if(path.match(/^\/local*/)) { console.log("it's local"); return null; } else { console.log("proxying"); return { host: "localhost", port: "7000", method: "proxy" //send request to server only //"both": send request to both me and the server }; } };
路由规则是:
*url中以local开头的不转发,包括html文件都放在local文件夹下(这样访问本地页面:http://localhost:7001/local/index.html)
*需要访问外部资源的时候,使用绝对路径,而不要使用相对路径。