背景介绍:

  开发微信公共号时前后端分离,后台用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);
}
}
}

  3:vue中axios.js

var url="/Wechat/JsonP/GetVueBranchList";
this.$http({
method: 'get',
dataType: "jsonp",
jsonp: "MoDoPMS",//jsonp接口参数
timeout: ,//超时
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});
}, );
})
.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=""/>
</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 信息了。

最新文章

  1. EntityFramework Core Raw SQL
  2. OC NSSet
  3. js获取缓存数据
  4. Notepad++的列编辑功能
  5. SQL逻辑读变成零
  6. UIAlertView用法
  7. MyContentProvider
  8. Linux下ThinkPHP网站目录权限设置
  9. [改善Java代码]避免对象的浅拷贝
  10. 如何自动拼接 Update语句,仅Update已修改的字段
  11. 59 pages的Delphi源码
  12. web项目的发布
  13. python用Django+Celery+Redis 监视程序(一)
  14. 在wamp集成环境下安装laravel5.2.*框架
  15. JQ简单实现无缝滚动
  16. LeetCoder题解之Find All Anagrams in a String
  17. odoo方法
  18. JAVA-数据库之更新记录
  19. chapter02“良/恶性乳腺癌肿瘤预测”的问题
  20. JSON概述及其在JavaScript与Java中的应用(整理)

热门文章

  1. jrebel 7免费激活(非破解) 和 IntelliJ Idea 2017 免费激活方法
  2. nginx 配置一个文件下载服务
  3. gsub
  4. mongodb - 集合重命名
  5. Linux 基础学习(第一节)
  6. linux按内容查找文件
  7. Android Studio公布到Jcenter
  8. Atitit.swt&#160;线程调用ui控件的方法
  9. C# 使用IP端口网络打印图片
  10. linux 查看可执行文件动态链接库相关信息(转)