一、前言

由于项目是前后端分离,API接口与Web前端 部署在不同站点当中,因此在前文当中WebApi Ajax 跨域请求解决方法(CORS实现)使用跨域处理方式处理而不用Jsonp的方式。

但是在一段时间后,发现一个很奇怪的问题,每次前端发起请求的时候,通过浏览器的开发者工具都能看到在Network下同一个url有两条请求,第一条请求的MethodOPTIONS,第二条请求的Method才是真正的Get或者Post,并且,第一条请求无数据返回,第二条请求才返回正常的数据。

二、原因

第一个OPTIONS的请求是由WEB服务器处理跨域访问引发的。OPTIONS是一种预检请求,浏览器在处理跨域访问的请求时,如果判断请求为复杂请求,则会先向服务器发送一条预检请求,根据服务器返回的内容,浏览器判断服务器是否允许访问该请求。如果WEB服务器采用CORS的方式支持跨域访问,在处理复杂请求时这个预检请求是不可避免的。

由于我们的WEB服务器采用CORS来解决跨域访问的问题,同时在header中添加了自定义参数以及使用json格式来进行数据交互,导致我们的每次请求都是复杂请求,从而产生每次请求都会发送两条请求的现象。

产生原因如下:

  • 使用CORS解决跨域问题

三、解决方案

3.1 Nginx

3.1.1 思路

  • 将前端项目部署在Nginx当中,通过代理的方式来解决跨域请求问题

3.1.2 实现

3.1.2.1 安装 Nginx

Windows 下 安装 Nginx 最简单,直接下载压缩包,然后解压后

3.1.2.2 配置 Nginx

已自带默认配置,如要部署VueAngular这种单页面应用,将打包后的index.html文件以及dist目录放到发布目录中,将路径复制,用于配置Nginx服务指向

配置文件如下:

    server {
listen 9461; # 监听端口号
server_name localhost 192.168.88.22; # 访问地址
location / {
root 项目路径; # 例如:E:/Publish/xxx/;
index index.html; # 此处用于处理 Vue、Angular、React 使用H5 的 History时 重写的问题
if (!-e $request_filename) {
rewrite ^(.*) /index.html last;
break;
}
} # 代理服务端接口
location /api {
proxy_pass http://localhost:9460/api;# 代理接口地址
}
}

3.1.2.3 Nginx 常用命令

  • 启动:start nginx
  • 重新加载配置:nginx -s reload
  • 重新打开日志文件:nginx -s reopen
  • 测试配置文件是否正确:nginx -t [可选:指定路径]
  • 快速停止:nginx -s stop
  • 有序停止:nginx -s quit

3.1.3 Nginx 单页面应用H5 History Url重写

  • 支持

    Vue、Angular、React
  • 原因

    实现单页面时,刷新页面会产生页面找不到的问题,所以需要重写Url地址到index.html当中。
  • 注意点

    在使用Nginx中URL重写的时候,一直报错如下



    检查后,发现 if( 之间必须有个空格。

3.2 Other

3.2.1 思路

  • 既然要发送预检请求,是否可以减少预检请求的次数?
  • 例如可以设定一个有效期,在有效期内不再重复预检。

3.2.2 实现

可以在服务端处预检完成后加入一个Access-Control-Max-Age请求头来解决这个问题。

3.2.3 CORS 响应字段说明

  • Access-Control-Allow-Methods

    该字段必需,它的值是逗号分隔的一个字符串,表明服务器支持的所有跨域请求的方法。

    注意,返回的是所有支持的方法,而不单是浏览器请求的那个方法。这是为了避免多次"预检"请求。
  • Access-Control-Allow-Headers

    如果浏览器请求包括Access-Control-Request-Headers字段,则Access-Control-Allow-Headers字段是必需的。

    它也是一个逗号分隔的字符串,表明服务器支持的所有头信息字段,不限于浏览器在"预检"中请求的字段。
  • Access-Control-Allow-Credentials

    该字段与简单请求时的含义相同。
  • Access-Control-Max-Age

    该字段可选,用来指定本次预检请求的有效期,单位为秒。上面结果中,有效期是20天(1728000秒),即允许缓存该条回应1728000秒(即20天),在此期间,不用发出另一条预检请求。
Access-Control-Allow-Methods: GET, POST, PUT
Access-Control-Allow-Headers: X-Custom-Header
Access-Control-Allow-Credentials: true
Access-Control-Max-Age: 1728000

四、参考文献

Nginx 解决WebApi跨域二次请求以及Vue单页面问题的更多相关文章

  1. 解决前后端调用,跨域二次请求Access-Control-Max-Age

    发现前后端分离的项目中,前端发起一个请求到后端,在Chrome浏览器下面debug的时候,Network下面看到同一个url有两条请求,url有两条请求,第一条请求的Method为OPTIONS,第二 ...

  2. 如何用Nginx解决前端跨域问题?

    前言 在开发静态页面时,类似Vue的应用,我们常会调用一些接口,这些接口极可能是跨域,然后浏览器就会报cross-origin问题不给调. 最简单的解决方法,就是把浏览器设为忽略安全问题,设置--di ...

  3. CORS解决WebApi跨域问题(转)

    CORS全称Cross-Origin Resource Sharing,中文全称跨域资源共享.它解决跨域问题的原理是通过向http的请求报文和响应报文里面加入相应的标识告诉浏览器它能访问哪些域名的请求 ...

  4. 【Nginx】在Windows下使用Nginx解决前端跨域问题

    提出问题:因为一些历史原因,后台代码不能动.请求别人的接口拿数据显示在前端,怎么办呢? 分析问题:通过ajax请求. 解决问题:因为浏览器的同源策略,所以需要解决跨域问题.(同源策略:请求的url地址 ...

  5. 使用筛选器特性标记方法解决webapi 跨域问题

    在我的之前随笔 解决api.WebService跨域问题 中有人问到可以用特性来解决跨域问题吗,答案是肯定的,可以的:操作如下: 首先建一个类CrossSiteAttribute:从抽象 Action ...

  6. 利用nginx解决cookie跨域

    一.写在前面 最近需要把阿里云上的四台服务器的项目迁移到客户提供的新的项目中,原来的四台服务器中用到了一级域名和二级域名.比如aaa.abc.com 和bbb.abc.com 和ccc.abc.com ...

  7. nginx解决浏览器跨域问题

    1.跨域问题 浏览器出于安全方面的考虑,只允许与本域下的接口交互.不同源的客户端脚本在没有明确授权的情况下,不能读写对方的资源. 例如访问www.test1.com 页面, 返回的文件中需要ajax向 ...

  8. 用nginx解决前端跨域问题

    假如前端你项目部署在nginx的根目录下,然后项目需要请求后台小伙伴写的接口 nginx配置: #user nobody; worker_processes 1; #error_log logs/er ...

  9. nginx解决前端跨域配置

    在nginx.conf文件中 添加如上配置: 在ajax中将原来的 url:http://192.168.1.127:8905/findItem 改成:'http://localhost/findIt ...

随机推荐

  1. Android异步消息机制

    Android中的异步消息机制分为四个部分:Message.Handler.MessageQueue和Looper. 其中,Message是线程之间传递的消息,其what.arg1.arg2字段可以携 ...

  2. Jarvis OJ - [XMAN]level1 - Writeup——简单shellcode利用

    100分的pwn 简单查看一下,果然还是比较简单的 放到ida中查看一下,有明显的溢出函数,并且在函数中打印出了字符串的地址,并且字符串比较长,没有NX保护 所以我们很容易想到构造shellcode, ...

  3. 编码中的setCharacterEncoding 理解<转自-fancychendong>

    1.pageEncoding="UTF-8"的作用是设置JSP编译成Servlet时使用的编码. 2.contentType="text/html;charset=UTF ...

  4. F04 我的投资策略

    我的投资理念:价值投资和右侧趋势投资.我的目标年化收益率: 15-25%我的投资时间:3-5年我的投资品种:股票 + EFT基金 买卖时间点的纪律(买入,卖出的时间原则)股票MA20为界限,高于则持有 ...

  5. ESL翻译:Linear Methods for Regression

    chapter 3: Linear Methods for Regression 第3章:回归的线性方法 3.1 Introduction A linear regression model assu ...

  6. Android studio导入eclipse项目(亲测)

    之前上网搜索的时候,网上都说先用eclipse导出gradle,之后再用Android Studio的import project导入,但是这个方法使用的过程中会出现许多错误,解决了一个又一个还是不得 ...

  7. 【java】正则表达式简单示例

    public class Test { public static void main(String[] args) { String str="135axy"; String r ...

  8. JavaScript基础2——关于变量

    变量的声明                            变量的定义:使用var关键字来声明,区分大小写的.注意:不用var,会污染全局变量.        变量的命名规范是:字母,数字,$符 ...

  9. vue+express之前后台分离博客

    说来惭愧,这么久没有更新过博客了,写个项目练练手吧,打算写一个vue+express的博客  可能这个时间说长不长说短不短  写到哪就是哪吧  我采用的是前后台分离  express采用的是mvc,但 ...

  10. iOS cocos2d安装以及问题解决

    一:下载: 首先要去Cocos2d和Cocos2d-x网站下载相关的工具: 1.Cocos2d下载地址:http://www.cocos2d-iphone.org,然后进入Download页面,下边有 ...