背景介绍:
开发微信公共号时前后端分离,后台用 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 中配置项
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 信息了。
来源: http://www.bubuko.com/infodetail-2452253.html