• 解决异地服务器接口访问跨域,node构建反向代理


         跨域对于前端来说是一个老大难的问题,许多方法如jsonpdocument.domain + iframe...都有或多或少的问题,一个最佳实践就是通过服务器nginx做反向代理,但奈何不懂相关知识,就一直琢磨着使用 node.js来做。

     

      之前公司php写的接口,然后用node定义一样的路由,前端请求node的接口,然后通过Node在控制器中访问php的接口,这样确实能解决跨域问题,不过也是有缺点的,不能带上cookic等信息,不等同于反向代理;

      

      事实上使用node是可以很容易构建本地的反向代理,使用 http-proxy-middleware 模块

      假如目前有一个php提供的接口为   http://api.text.com/getdata  需要去代理

      首先  

    npm i  http-proxy-middleware --save   //反向代理包
    npm i cors  --save            //node跨域模块 

     然后:生成一个新的 express,app.js里面 删掉 index和user这两个路由,然后

    var cors = require('cors');
    var proxy = require('http-proxy-middleware');
    var options = {
        target: 'http://api.text.com', // 目标主机,提供接口服务的域名
        changeOrigin: true,               // 需要虚拟主机站点
    };
    var exampleProxy = proxy(options);  //开启代理功能,并加载配置

      

    app.use(cors());
    
    app.use(exampleProxy);  //代理任意请求的路由,也可以改成代理固定的某些路由
    

    启动express服务

    前段代码:

    const host = "http://127.0.0.1:3000";
    $.ajax({
    url: host+ "/getdata"
    }).then(function(data){
    console.log(data);
    }).fail(function(error){
    console.log(error);
    });

    目前为止,反向代理成功,本地电脑可以跨域访问远程服务接口

    另外,附加上,自己写的一个,携带cookic 的转发:

    roouter.js 文件

    var express = require('express');
    var router = express.Router();
    var request = require("request");
    /* GET home page. */
    
    
    
    const Api = {
    	GET(params){
    		params = params || {};
    		return new Promise(function(resolve,reject){
    			request({
    				method:"GET",
    				url:params.url,
    				qs:params.data,
    				headers:params.headers
    			},function (error, response, body) {
    			    if (!error) {
    					resolve({response,body});
    			    }else{
    					reject(error);
    			    }
    			});
    		})
    		
    	},
    	POST(params){
    		params = params || {};
    		return new Promise(function(resolve,reject){
    			request({
    				method:"POST",
    				url:params.url,
    				form:params.data,
    				headers:params.headers
    			},function (error, response, body) {
    			    if (!error) {
    					resolve({response,body});
    			    }else{
    					reject(error);
    			    }
    			});
    		})
    	}
    }
    
    
    
    module.exports = function(opt){
    	opt  = opt || {};
    	var target = opt.target || '';
    	var url = opt.url || "**";
    	router.all(url,function(req,res,next){
    		var url = target + req.baseUrl + req.path;
    		var data = {};
    		var method = req.method;
    		if(method =="GET"){
    			data = req.query;
    		}else if(method == "POST"){
    			data = req.body;
    		}
    		let Cookie =  req.header("Cookie");
    		let content = req.header('Content-type');
    		console.log("url:"+url,data,Cookie,content);
    		data.headers = {
    			"content-type": content,
    			"Cookie":Cookie
    		};
    		if(Api[req.method]){
    			Api[req.method]({
    				url:url,
    				data:data
    			}).then(function({response,body}){
    				try{
    					body = JSON.parse(body);
    				}catch(e){
    				}
    				// ************** 透传响应中的cookie **************
                    if (response.headers['set-cookie']) {
                        res.setHeader("set-cookie", response.headers['set-cookie']);
    				}
    				
                    // ************** 自定义cookie **************
    				//res.cookie('tc', 'test-cookie', {maxAge: 2 * 60 * 60 * 1000, httpOnly: true});
    
                    return res.status(response.statusCode).send(body);
    			   //return res.json(body);
    			}).catch(function(e){
    				res.json(e);
    			})
    		}else{
    			res.json({code:500,msg:"不支持的请求类型"});
    		}
    	})
    	return router;
    };
    

      

      

    index.js

    var express = require('express');
    var router = require("./routers");
    
    
    var cors = require('cors');
    
    var app = express();
    
    app.use(express.json());
    app.use(express.urlencoded({ extended: false }));
    app.use(cors());
    
    
    var config = {
    	target:"http://xxxxxx"
    };
    
    app.use("/",router(config));
    
    app.listen("3000",function(error){
    	console.log("启动服务-----3000");
    })
    

      

    koa2 版本

    const router = require('koa-router')()
    
    var request = require("request");
    /* GET home page. */
    
    
    
    const Api = {
    	GET(params){
    		params = params || {};
    		return new Promise(function(resolve,reject){
    			request({
    				method:"GET",
    				url:params.url,
    				qs:params.data
    			},function (error, response, body) {
    			    if (!error && response.statusCode == 200) {
    			        try{
    						body = JSON.parse(body);
    					} catch(e){
    						
    					}
    					resolve(body);
    			    }else{
    					reject(error);
    			    }
    			});
    		})
    		
    	},
    	POST(params){
    		params = params || {};
    		return new Promise(function(resolve,reject){
    			request({
    				method:"POST",
    				url:params.url,
    				form:params.data
    			},function (error, response, body) {
    			    if (!error && response.statusCode == 200) {
    			        try{
    						body = JSON.parse(body);
    					} catch(e){
    						
    					}
    					resolve(body);
    			    }else{
    					reject(error);
    			    }
    			});
    		})
    	}
    }
    
    module.exports = function(opt){
    	opt  = opt || {};
    	var target = opt.target || '';
    	var url = opt.url || "**";
    	if(opt.prefix){
    		router.prefix(opt.prefix)
    	}
    	router.all(url,async function(ctx,next){
    		var url = target  + ctx.path;
    	
    		var data = {};
    		if(ctx.method =="GET"){
    			data = ctx.query;
    		}else if(ctx.method == "POST"){
    			data = ctx.request.body;
    		}
    		console.log("请求来源:"+url,data,ctx.method);
    		if(Api[ctx.method]){
    			try{
    			ctx.body =	await Api[ctx.method]({
    					url:url,
    					data:data
    				});
    			}catch(e){
    				ctx.body = e;
    			}
    		
    		}else{
    			ctx.body = {code:500,msg:"不支持的请求类型"};
    		}
    	})
    	return router;
    };
    

      

     

    使用:

    const proxy = require('./routers');
    
    const insproxy = proxy({
      target:"xxxx",
      prefix:"/xxx"
    });
    
    app.use(insproxy.routes(), insproxy.allowedMethods());
    

      

  • 相关阅读:
    docker介绍与安装
    HTML5之Notification简单使用
    移动端实现复制内容至剪贴板
    flex基本概念
    nodejs建立websocket通信
    使用FileReader实现前端预览所选图片
    去除字符串中的空格
    用swing做一个简单的正则验证工具
    使用命令行生成jar包
    C#语言 语句
  • 原文地址:https://www.cnblogs.com/muamaker/p/7495829.html
Copyright © 2020-2023  润新知