首页 > 系统相关 >Nginx跨域问题

Nginx跨域问题

时间:2024-07-02 15:58:30浏览次数:19  
标签:Control Access http 跨域 js 问题 Nginx com

目录

Nginx跨域实现

首先大家要搞清楚什么是跨域,为什么会有跨域情况的出现。哪些情况属于跨域?
跨域:由于浏览器的同源策略,即属于不同域的页面之间不能相互访问各自的页面内容
注:同源策略,单说来就是同协议,同域名,同端口

URL 说明 是否允许通信
http://www.a.com/a.js
http://www.a.com/b.js 同一域名下 允许

http://www.a.com/lab/a.js
http://www.a.com/script/b.js 同一域名下不同文件夹 允许

http://www.a.com:8000/a.js
http://www.a.com/b.js 同一域名,不同端口 不允许

http://www.a.com/a.js
https://www.a.com/b.js 同一域名,不同协议 不允许

http://www.a.com/a.js
http://70.32.92.74/b.js 域名和域名对应ip 不允许

http://www.a.com/a.js
http://script.a.com/b.js 主域相同,子域不同 不允许

http://www.a.com/a.js
http://a.com/b.js 同一域名,不同二级域名(同上) 不允许(cookie这种情况下也不允许访问)

http://www.cnblogs.com/a.js
http://www.a.com/b.js 不同域名 不允许

跨域场景

出于安全考虑(比如csrf攻击),浏览器一般会禁止进行跨域访问,但是因为有时有相应需求,需要允许跨域访问,这时,我们就需要将跨域访问限制打开。
启动一个web服务,端口是8081。

然后再开启一个web服务/前端服务都可以。端口是8082,然后再8082的服务中通过ajax来访问8081的服务,这就不满足同源策略,就会出现跨域问题。

<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%>
<html>
<head>
    <meta http-equiv="content-type" content="text/html; charset=utf-8">
</head>
<body>
<h2>Hello World!</h2>
<script type="text/javascript">
    function fun1(){
        var request = new XMLHttpRequest();
        request.open("GET","http://localhost:8081/user/query")
        request.send();
        request.onreadystatechange = function(){
            if(request.status==200 && request.readyState == 4){
                console.log("响应的结果" + request.responseText)
            }
        }
    }
</script>
</body>
    <input type="button" value="跨域调用" onclick="fun1()">
</html>

跨域问题的解决方案

解决跨域问题的方式也有多种:
1.前后端结合(JsonP)
虽然jsonp也可以实现跨域,但是因为jsonp不支持post请求,应用场景受到很大限制,所以这里不对jsonp作介绍。

2.纯后端方式一(CORS方式)
CORS是w3c标准的方式,通过在web服务器端设置:响应头Access-Cntrol-Alow-Origin来指定哪些域可以访问本域的数据,ie8&9(XDomainRequest),10+,chrom4,firefox3.5,safair4,opera12支持这种方式。

服务器代理,同源策略只存在浏览器端,通过服务器转发请求可以达到跨域请求的目的,劣势:增加服务器的负担,且访问速度慢。

3.纯后端方式二(Nginx代理方式)

首先配置Nginx的反向代理方式

代理访问正常

8082的服务访问Nginx,出现了跨域问题

Nginx配置跨域解决

nginx配置如下:

location / {  
    add_header Access-Control-Allow-Origin *;
    add_header Access-Control-Allow-Methods 'GET, POST, OPTIONS';
    add_header Access-Control-Allow-Headers 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization';

    if ($request_method = 'OPTIONS') {
        return 204;
}
proxy_pass http://192.168.12.1:8081;
} 

解决了跨域问题

参数说明
Access-Control-Allow-Origin
服务器默认是不被允许跨域的。给Nginx服务器配置Access-Control-Allow-Origin *后,表示服务器可以接受所有的请求源(Origin),即接受所有跨域的请求。

Access-Control-Allow-Headers
是为了防止出现以下错误:
Request header field Content-Type is not allowed by Access-Control-Allow-Headers in preflight response.
这个错误表示当前请求Content-Type的值不被支持。其实是我们发起了"application/json"的类型请求导致的。这里涉及到一个概念:预检请求(preflight request)

Access-Control-Allow-Methods
是为了防止出现以下错误:
Content-Type is not allowed by Access-Control-Allow-Headers in preflight response.

给OPTIONS添加204的返回
是为了处理在发送POST请求时Nginx依然拒绝访问的错误,发送"预检请求"时,需要用到方法OPTIONS,所以服务器需要允许该方法。

预检请求(preflight request)
跨域资源共享(CORS)标准新增了一组 HTTP 首部字段,允许服务器声明哪些源站有权限访问哪些资源。另外,规范要求,对那些可能对服务器数据产生副作用的HTTP 请求方法(特别是GET以外的HTTP请求,或者搭配某些 MIME 类型的 POST 请求),浏览器必须首先使用 OPTIONS 方法发起一个预检请求(preflight request),从而获知服务端是否允许该跨域请求。服务器确认允许之后,才发起实际的 HTTP 请求。在预检请求的返回中,服务器端也可以通知客户端,是否需要携带身份凭证(包括 Cookies 和 HTTP 认证相关数据)。
其实Content-Type字段的类型为application/json的请求就是上面所说的搭配某些 MIME 类型的 POST 请求,CORS规定,Content-Type不属于以下MIME类型的,都属于预检请求
所以 application/json的请求 会在正式通信之前,增加一次"预检"请求,这次"预检"请求会带上头部信息 Access-Control-Request-Headers: Content-Type:

OPTIONS /api/test HTTP/1.1
Origin: http://foo.example
Access-Control-Request-Method: POST
Access-Control-Request-Headers: Content-Type
... 

服务器回应时,返回的头部信息如果不包含Access-Control-Allow-Headers: Content-Type则表示不接受非默认的的Content-Type。
即出现以下错误:
Request header field Content-Type is not allowed by Access-Control-Allow-Headers in preflight response.

标签:Control,Access,http,跨域,js,问题,Nginx,com
From: https://www.cnblogs.com/even160941/p/18280015

相关文章

  • 网络安全:Nginx安全问题使1400多万台服务器容易受到ddos攻击
    据外媒报道,近日nginx被爆出存在安全问题,有可能会致使1400多万台服务器易遭受DoS攻击。而导致安全问题的漏洞存在于HTTP/2和MP4模块中。新版本的NginxWeb服务器已于11月6日发布,用于修复影响1.15.6,1.14.1之前版本的多个安全问题,该漏洞允许潜在的攻击者触发拒绝服务(Do......
  • POST和GET请求乱码问题
    简介:在很多情况下我们使用get或者post请求时会出现乱码问题。本文的目标是教会读者解决该问题。1.get请求乱码问题使用get请求提交数据时,数据会回显在uri上,例如:/springmvc/login?username=张三&password=123(注意:这不是一个很好的示范username和password这种敏感信息不应该使用......
  • C++编译问题,解决arm下链接静态库,引起的relocation R_AARCH64_ADR_PREL_PG_HI21 agains
    显示的完整错误如下:relocationR_AARCH64_ADR_PREL_PG_HI21againstsymbol`ZN2c43yml9free_implEPvmS1'whichmaybindexternallycannotbeusedwhenmakingasharedobject;recompilewith-fPIC根据提示,在链接.a静态库时,应该在编译时加上参数-fPIC然而CMake文件中已......
  • Nginx(openresty) X-Forwarded-For $proxy_add_x_forwarded_for 多层代理 通过map分割
    1nginx配置#配置多层反向代理,配置如下proxy_passhttp://ip或者域名/;proxy_connect_timeout60;proxy_send_timeout60;proxy_read_timeout60;proxy_set_headerUpgrade$h......
  • 十四、Redis应用问题解决
    文章目录一、缓存穿透1.1问题描述1.2解决方案二、缓存击穿2.1问题描述2.2解决方案三、缓存雪崩3.1问题描述3.2解决方案四、分布式锁4.1问题描述4.2解决方案:使用redis实现分布式锁4.3编写代码4.4优化之设置锁的过期时间4.5优化之UUID防误删4.6优化之LUA脚......
  • 腾讯云服务器上安装mysql,本地windows机器通过heidisql客户端连接引发的问题
    一、问题描述1.腾讯云服务器上docker方式安装完mysql后,windows电脑上heidisql客户端不用密码就能连接2.修改docker里mysql密码,heidisql客户端就连接不上了二、问题排查1.不用密码就能连接是因为mysql的配置文件中有设置skip-grant-tables参数(1)dockerinspectsmysql查看挂......
  • Outlook发送大文件的问题是什么?怎么解决?
    Outlook不仅是一款电子邮件客户端,还包括日历、任务、笔记、联系人等功能,同时与MicrosoftOffice套件中的其他应用程序(如Word、Excel、PowerPoint等)集成紧密,方便用户在不同应用程序之间切换,提高工作效率。因此,Outlook邮箱在全球范围内都广泛应用。但Outlook也有许多明显的缺陷:加......
  • 达梦数据库迁移常见语法问题
    数据库迁移常见语法问题DM数据库常见语法差异一.Sql文语法1.杀进程语法select*fromv$lock;select*fromsysobjects;--(查询对象信息)select*fromv$sessions;--(查询会话信息)--上述3条语句组合一下就能查出哪张表上的某种锁是由哪个会话里的操作加上的--查哪张表上......
  • 通过更改java环境变量修改java版本不生效问题
    目录问题复现解决方法问题复现本地生产环境时java8,但是新项目需要java11.于是我下载了jdk11,并修改了环境变量。之后使用java-version,发现java版本还是8,并没没有更改成11解决方法参考文章输入wherejava将这个路径下的java.exe删除就好了。......
  • 突破SQL基本面试问题(0)
    写作原因:在当今数据驱动的商业环境中,SQL作为数据分析师的核心工具,其重要性日益凸显。它不仅是查询和操作数据库的语言,更是连接数据与洞察力的桥梁。随着大数据技术的飞速发展,众多顶级企业,包括华为等大厂,已经将SQL基础能力的考察纳入到面试流程中,作为评估候选人是否具备高效......