zoukankan      html  css  js  c++  java
  • nginx 解决ajax post跨域问题 以及出现该跨域的本质原因

    背景:服务器语言为Java 框架Springboot  PostMapping   RequestBody 

       前端 js Ajax请求 content-type application/json 

       浏览器报跨域

    原因

    原来在使用Ajax跨域请求时,如果设置Header的ContentType为application/json,会分两次发送请求。第一次先发送Method为OPTIONS的请求到服务器,这个请求会询问服务器支持哪些请求方法(GET,POST等),支持哪些请求头等等服务器的支持情况。等到这个请求返回后,如果原来我们准备发送的请求符合服务器的规则,那么才会继续发送第二个请求,否则会在Console中报错。

    为什么在跨域的时候设置ContentType为application/json时会请求两次?其实JQuery的文档对此有做说明。

    contentType (default: 'application/x-www-form-urlencoded; charset=UTF-8')

    Type: Boolean or String

    When sending data to the server, use this content type. Default is "application/x-www-form-urlencoded; charset=UTF-8", which is fine for most cases. If you explicitly pass in a content-type to $.ajax(), then it is always sent to the server (even if no data is sent). As of jQuery 1.6 you can pass false to tell jQuery to not set any content type header. Note: The W3C XMLHttpRequest specification dictates that the charset is always UTF-8; specifying another charset will not force the browser to change the encoding. Note: For cross-domain requests, setting the content type to anything other than application/x-www-form-urlencoded, multipart/form-data, or text/plain will trigger the browser to send a preflight OPTIONS request to the server.

    注意Note后面的描述,在跨域的时候,除了contentType为application/x-www-form-urlencoded,multipart/form-data或者text/plain外,都会触发浏览器先发送方法为OPTIONS的请求。

    比如说,你原来的请求是方法方法POST,如果第一个请求返回的结果Header中的Allow属性并没有POST方法,那么第二个请求是不会发送的,此时浏览器控制台会报错,告诉你POST方法并不被服务器支持。

    之前的跨域配置 

    add_header 'Access-Control-Allow-Origin' '*';
    add_header 'Access-Control-Allow-Credentials' 'true';
    add_header 'Access-Control-Allow-Methods' 'GET,POST,OPTIONS';

    nginx解决方案 将下方代码放置对应的location内 重点是OPTIONS处理:

    if ($request_method = 'OPTIONS') {
            add_header 'Access-Control-Allow-Origin' '*';
            add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
            add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';
            add_header 'Access-Control-Max-Age' 1728000;
            add_header 'Content-Type' 'text/plain charset=UTF-8';
            add_header 'Content-Length' 0;
            return 204;
           }
           if ($request_method = 'POST') {
            add_header 'Access-Control-Allow-Origin' '*';
            add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
            add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';
           }
           if ($request_method = 'GET') {
            add_header 'Access-Control-Allow-Origin' '*';
            add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
            add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';
           }
  • 相关阅读:
    ConnectionUtils
    设置组件内容模板和头部模板
    设置idea 代码模板
    Win10 安装流程 Maven
    IDEA: Error:java: 无效的源发行版: 9
    eclipse js的自动提示
    SQLserver SQL语句自动格式化工具的调出
    java计算两个n阶矩阵相乘
    JSP页面输出数据库表格
    threadpool 的配置实用
  • 原文地址:https://www.cnblogs.com/AmbitiousMice/p/15726423.html
Copyright © 2011-2022 走看看