下面我以简单的两台node服务器来说明如何使用nginx进行前端跨域访问。

  1. node1服务器 在localhost:8083上启动
const app = express();
app.get('/web/users',(req, res)=>{res.json([{name:"张三",age:12},{name:"李四",age:14}]);res.end()
})
app.listen(process.env.PORT || 8083);
复制代码

同域下的前端代码只需调用

function getUsers() {var xhr=new XMLHttpRequest();xhr.open('GET', 'http://localhost:8083/web/users');xhr.send(null);xhr.onreadystatechange = function () {if (xhr.readyState == 4 && xhr.status == 200) {alert(xhr.responseText);}else {alert(xhr.statusText);}}
}
复制代码

这里有一点需要关注的是,前后端代码处在同一个域下,xhr.open() url路径写成下面这样也是可以的,它会默认请求到http://localhost:8083/web/users

xhr.open('GET', '/web/users');
复制代码

下面我们将node1服务器中的web/users接口删除:

const app = express();
app.listen(process.env.PORT || 8083);
复制代码

前端此时自然无法访问后台的web/users了,将报一个404错误。

下面增加一个node2服务器,在localhost:8085上启动,同时我们将原先在8083上删除的web/users接口搬迁到8085上:

const app = express();
app.get('/web/users',(req, res)=>{res.json([{name:"张三",age:12},{name:"李四",age:14}]);res.end()
})
app.listen(process.env.PORT || 8085);
复制代码

由于8085实现了这个接口,我们尝试在原先8083端口下的ajax调用它试试:

 xhr.open('GET', 'http://localhost:8085/web/users');
复制代码

如我们所料,浏览器阻止了此次行为,并抛出一个跨域错误。

难道就无法访问那个接口了吗?其实服务器之间和服务器之间是可以相互调用的,阻止跨域访问只是在浏览器端做的限制而已。

下面我通过两种方式来实现如何访问到8085上的web/users接口。

1 . node直接作为代理访问

原理就是交由8083后端去访问8085端口接口,访问完成交给前端
8083node后端实现代码:

npm install request --save // 需要安装一个http request模块
复制代码
const app = express()
const request = require('request')
// 访问此接口时通过request模块去访问8085 再返回给前端。
app.get('/web/users',(req, res)=>{var url='http://localhost:8085'+req.urlconsole.log(url) // http://localhost:8085/web/usersreq.pipe(request(url)).pipe(res);
})
复制代码

2. jsonp方式访问

就是通过script 的src,向服务器请求数据,且这不受同源策略限制;然后服务器将相应的数据放入指定的函数回调名中,返回给前端。说的有点绕,下面通过实例讲解: 8083前端请求8085,这里已经不再是ajax请求了,而是直接加载8085上资源。

 <script>function getUsers(data) {alert(data)}</script><script src="http://localhost:8085/jsonp?callback=getUsers"></script>
复制代码

上述代码第一个script标签定义了一个函数getUsers 但是并没有执行,只是定义了而已,要想有执行能力,需要

getUsers(data)
复制代码

所以我们要让第二个标签script src="http://localhost:8085/jsonp?callback=getUsers" 返回getUsers(data)内容即可,这样第一个标签内定义的函数就可以执行了。返回接口内容只需要放到函数参数里即可
后台8085实现:

const app = express();
const querystring=require('querystring')
const url=require('url')// 处理前端jsonp请求
app.get('/jsonp',(req,res)=>{var qs = querystring.parse(req.url.split('?')[1]); //{callback:'getUsers'}var users=JSON.stringify([{name:"张三",age:12},{name:"李四",age:14}]) // 注意需要传成字符串格式var callback=`${qs.callback}(${users})`res.end(callback)
})
复制代码

前端返回

是不是有点黑魔法的味道!但是缺点也是明显的,首先通过此方式有一定安全性的,通过callback后加一些乱七八糟的东西可能会有xss攻击,最主要的是jsonp不支持post方法。

3 .nginx反向代理器

此方式即类似于第一种node代理方式,也是通过服务器和服务器之间通信,只是不需要8083下后台服务器自己去访问8085,而是专门交给nginx,为什么?姑且认为nginx更加专业吧! nginx配置

server {listen 8007;          # nginx启动端口,需要访问这个端口才能够代理server_name localhost:8083; # 需要代理的服务器location / {          # 如果你访问127.0.0.1/8002/的话nginx去请求proxy_pass http://localhost:8083;}location /web { #访问/web/aa时会映射成http://localhost:8085/web/aa;proxy_pass   http://localhost:8085;}}
复制代码

8083请求路径

xhr.open('GET', '/web/users');
复制代码

3 CORS

CORS全称是跨域资源共享 是一个W3C标准,它规定浏览器允许发送ajax到不同域下的服务器来获取数据,从而克服了原来限制,使用CORS需要前后端都支持,现代浏览器基本上都支持。具体CORS的知识可以参考阮一峰博客 www.ruanyifeng.com/blog/2016/0…

app.use('*',function (req, res, next) {res.header('Access-Control-Allow-Origin', '*'); //这个表示任意域名都可以访问,这样写不能携带cookie了。
//res.header('Access-Control-Allow-Origin', 'http://www.baidu.com'); //这样写,只有www.baidu.com 可以访问。res.header('Access-Control-Allow-Headers', 'Content-Type, Content-Length, Authorization, Accept, X-Requested-With , yourHeaderFeild');res.header('Access-Control-Allow-Methods', 'PUT, POST, GET, DELETE, OPTIONS');//设置方法if (req.method == 'OPTIONS') {res.send(200); }else {next();}
});
复制代码

或者使用现成的CORS模块

npm install cors
复制代码
var express = require('express')
var cors = require('cors')
var app = express()var corsOptions = {origin: 'http://www.baidu.com',optionsSuccessStatus: 200
}app.get('/products/:id', cors(corsOptions), function (req, res, next) {res.json({msg: '只有百度可以访问'})
})app.listen(80, function () {console.log('CORS-enabled web server listening on port 80')
})
复制代码

如有不正确,请指正^_^

前端跨域问题解决方案汇总相关推荐

  1. 关于前端跨域及解决方案详解

    关于前端跨域 跨域指的是一个域下的文档或脚本试图去请求另一个域下的资源.我们常说的跨域,也就是指由浏览器同源策略限制的一类请求场景. 同源指的是协议,域名和端口号相同,一旦有一个不相同,则为不同源.同 ...

  2. Vue 前端跨域的解决方案(心得记录)

    背景: 今天面试一面和二面都还ok,三面是两个小姐姐(工作性质应该是外包驻场,所以有甲方来面),简历上巴拉巴拉的简单聊了一下,到了关键了,小姐姐说问一下基础的东西(这也是最怕的,毕竟Vue我之前用的挺 ...

  3. 前端跨域请求get_解决前端跨域问题方案汇总

    1.同源策略如下: URL 说明 是否允许通信 http://www.a.com/a.js http://www.a.com/b.js 同一域名下 允许 http://www.a.com/lab/a. ...

  4. 【精品】SpringBoot跨域请求 解决方案汇总

    代码下载地址:本博客示例代码 第一步:创建前端页面 项目结构图 页面代码 <!DOCTYPE html> <html lang="zh-cn"> <h ...

  5. 前端跨域问题解决方案

    proxyTable   主要开发环境使用. 发布线上nginx 配置 来自互联网参考:https://www.cnblogs.com/webhmy/p/9340361.html 转载于:https: ...

  6. 前端跨域问题的几种解决方案

    前端跨域问题的几种解决方案 参考文章: (1)前端跨域问题的几种解决方案 (2)https://www.cnblogs.com/xinxingyu/p/6075881.html 备忘一下.

  7. JSON Web Token(缩写 JWT) 目前最流行、最常见的跨域认证解决方案,前端后端都需要会使用的东西

    JSON Web Token(缩写 JWT)是目前最流行,也是最常见的跨域认证解决方案.无论是咱们后端小伙伴,还是前端小伙伴对都是需要了解. 本文介绍它的原理.使用场景.用法. 关于封面:这个冬天你过 ...

  8. 前端跨域,nginx反向代理的解决方案

    前端跨域,nginx反向代理的解决方案 参考文章: (1)前端跨域,nginx反向代理的解决方案 (2)https://www.cnblogs.com/Yukiyi/p/7912223.html (3 ...

  9. 深入理解前端跨域问题的解决方案——前端面试

    深入理解前端跨域问题的解决方案--前端面试 参考文章: (1)深入理解前端跨域问题的解决方案--前端面试 (2)https://www.cnblogs.com/greatluoluo/p/627346 ...

最新文章

  1. python wx窗口无法关闭_菜鸟学Python,双手奉上老司机给上路新手总结的Python实战问题…...
  2. Windows Server 2008 R2模板机制作(VMware Workstation)
  3. how to force opened by browser
  4. byte数组和hexstring互相转换
  5. java打开db文件_java 读取DB.properties文件方式 | 学步园
  6. 709. 转换成小写字母
  7. 【HDU - 5968】异或密码(思维,STLmap)
  8. java遍历斐波纳契数列_详解循环、迭代、递归、分治(Leet Code 509 斐波那契数列),实际运用...
  9. swift java_swift语法和java的比较
  10. MySQL-bin.index no found (errcode:13-perssion)
  11. 经典机器学习系列(十三)【结构化学习】
  12. Visual Studio开源库集成器Vcpkg全教程--利用Vcpkg轻松集成开源第三方库
  13. 每天数千个漏洞被公开 选什么工具能让漏洞追不上我?RASP介绍
  14. 如何在AI时代验证您的IT职业生涯
  15. redis的高级教程
  16. 服务器更新维护公告语,6月1日阴阳师服务器更新维护内容公告
  17. 前端海报生成的不同方案和优劣
  18. centos7.x系统磁盘lvm扩容
  19. JimuReport积木报表(SQLserver)主子表关联查询
  20. miix4linux双系统,miix4怎么装系统

热门文章

  1. Python文件夹与文件的操作
  2. Android下EditText中的字体不统一问题
  3. android jni jstring 转 char*
  4. Android studio编译好的apk文件在哪里?
  5. 【转】React 16 中从 setState 返回 null 的妙用
  6. (原)各种输入框美化
  7. Python之路:线程池
  8. 二叉树的左右子树交换
  9. Python3+Selenium3自动化测试-(一)
  10. margin塌陷问题