zoukankan      html  css  js  c++  java
  • c# vue 跨域get post cookie等问题

    背景介绍:

      开发微信公共号时前后端分离,后台用C#开发,前端使用vue框架,数据采用axios传输


    具体问题:

      1:前后端分离造成的跨域访问问题

      2:跨域后cookie传输和设置问题


    解决方案:

      1:使用jsonp作为数据传输的方式,前端和后端配合解决跨域问题

      2:通过设置webconfig配合axios.js解决cookie传输(get、set)


    具体方案:

      问题一:

      1:controller

        /// <summary>
            /// get
            /// </summary>
            /// <param name="ID"></param>
            /// <returns></returns>
            public JsonpResult Text(int ID)
            {
                return this.Jsonp(ID);
            }
            /// <summary>
            /// post
            /// </summary>
            /// <param name="jsonp"></param>
            /// <returns></returns>
            [HttpPost]
            public JsonpResult TextJsonpHttp(string jsonp)
            {
                return this.Jsonp(jsonp);
            }

      2:JsonpResult

     /// <summary>  
        /// Controller控制器类的扩展方法,即:Controller控制器下扩展一个Jsonp方法,这个方法带一个object类型的参数  
        /// </summary>  
        public static class ControllerExtension
        {
            public static JsonpResult Jsonp(this Controller controller, object data)
            {
                JsonpResult result = new JsonpResult()
                {
                    Data = data,
                    JsonRequestBehavior = JsonRequestBehavior.AllowGet
                };
                return result;
            }
        }
        public class JsonpResult : JsonResult
        {
            public static readonly string JsonpCallbackName = "MoDoPMS";//js中设置的jsonp
            public static readonly string CallbackApplicationType = "application/json";
            public override void ExecuteResult(ControllerContext context)
            {
                if (context == null)
                {
                    throw new AccessViolationException("context");
                }
    
                if (JsonRequestBehavior == JsonRequestBehavior.DenyGet && string.Equals(context.HttpContext.Request.HttpMethod, "GET", StringComparison.OrdinalIgnoreCase)) //如果不允许来自客户端的Get请求,并且请求类型是Get  
                {
                    throw new AccessViolationException();
                }
                var response = context.HttpContext.Response;
                if (!string.IsNullOrEmpty(ContentType)) //这个ContentType是获取或设置内容的类型。它是JsonResult类中的一个属性  
                {
                    response.ContentType = ContentType; //设置响应内容的类型  
                }
                else
                {
                    response.ContentType = CallbackApplicationType; //设置响应内容的类型  
                }
                if (ContentEncoding != null)
                {
                    response.ContentEncoding = this.ContentEncoding;//设置响应内容的编码  
                }
    
                if (Data != null) //这个Data是JsonResult类中的一个属性  
                {
                    string buffer;
                    var request = context.HttpContext.Request;
                    JsonSerializerSettings settings = new JsonSerializerSettings();
                    settings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
                    if (request[JsonpCallbackName] != null) //获取回调函数名称 
                    {
                        buffer = String.Format("{0}({1})", request[JsonpCallbackName], JsonConvert.SerializeObject(Data, Formatting.None, settings));//首先根据callback获取获取函数名,然后传入json字符串作为函数参数  
                    }
                    else
                    {
                        buffer = JsonConvert.SerializeObject(Data, settings);//首先根据callback获取获取函数名,然后传入json字符串作为函数参数  
                    }
                    response.Write(buffer);
                }
            }
        }
    View Code

      3:vue中axios.js

    var url="/Wechat/JsonP/GetVueBranchList";      
    this.$http({
            method: 'get',
            dataType: "jsonp",
          jsonp: "MoDoPMS",//jsonp接口参数
          timeout: 10000,//超时
          url: url,
        })
        .then(function(response){
    
        });
    get
      axios.post('/Wechat/JsonP/PostVueLogin', qs.stringify({loginphone:_this.phone,loginpwd:_this.password}))
            .then(response => {
              console.log(response);
              let instance = Toast(response.data.Message);
                setTimeout(() => {
                  instance.close();
                  _this.$router.push({name: response.data.Url});
                }, 1000);
            })
            .catch(err => {
              console.log(err);
            });
    post

      get与post均可使用axios.js

      4:配置项web.config

      <system.webServer>
    <httpProtocol>
          <customHeaders>
             
            <add name="Access-Control-Allow-Origin" value="*" /><!--解决跨域问题-->
            <add name="Access-Control-Allow-Methods" value="POST,GET" /><!--解决提交方式问题-->
          </customHeaders>
        </httpProtocol>
      </system.webServer>
    web.config

     


     问题二:

     1:web.config中配置项

     <system.webServer> 
    <httpProtocol>
          <customHeaders>
            <!--上线后将这里改为微信端的域名-->
            <add name="Access-Control-Allow-Origin" value="http://localhost:8080" /><!--解决跨域问题-->
            <add name="Access-Control-Allow-Methods" value="POST,GET,OPTIONS" /><!--解决提交方式问题-->
            <add name="Access-Control-Allow-Credentials" value="true" /><!--解决cookie问题-->
            <add name="Access-Control-Max-Age" value="1000"/>
          </customHeaders>
        </httpProtocol>
      </system.webServer>

      很多人问题出在这里

      The credentials mode of an XMLHttpRequest is controlled by the withCredentia

      原因是将origin设置成*,*可以解决跨域问题,但是如果想配合使用cookie就必须设置固定域名,如果设置两个,则会有一个不起作用。这里参考了简书 CSDN 中的一些理论

     2:vue-main.js中

      axios.defaults.withCredentials = true//解决cookie问题

     3:axios请求

     4:http header

     得到结论,在跨域的情况下使用 axios,首先需要配置 axios 的 withCredentials 属性为 true。然后服务器还需要配置响应报文头部的 Access-Control-Allow-Origin 和 Access-Control-Allow-Credentials 两个字段,Access-Control-Allow-Origin 字段的值需要为确定的域名,而不能直接用 ‘*’ 代替,Access-Control-Allow-Credentials 的值需要设置为 true。前端和服务端两边都配置完善之后就可以正常进行跨域访问以及携带 cookie 信息了。

  • 相关阅读:
    Java动态规划实现将数组拆分成相等的两部分
    动态规划解决hdu龟兔赛跑
    Eclipse上将maven项目部署到tomcat,本地tomcat下,webapps下,web-inf下lib下没有jar包决绝方案
    【转】spring IOC和AOP的理解
    Eclipse创建一个普通的java web项目
    linux服务器自动备份与删除postgres数据库数据
    开启Linux服务器vnc远程桌面详细步骤
    设计模式---JDK动态代理和CGLIB代理
    菜谱
    网络协议-dubbo协议
  • 原文地址:https://www.cnblogs.com/zhaokunbokeyuan256/p/8214974.html
Copyright © 2011-2022 走看看