您的位置:

首页 >

网络编程 >

JS跨域解决方案之使用CORS实现跨域 >

JS跨域解决方案之使用CORS实现跨域

2016-05-08 15:33:13

分类:网络编程

引言       跨域是我在日常面试中经常会问到的问题,这词在前端界出现的频率不低,主要原因还是由于安全限制(同源策略, 即JavaScript或Cookie只能访问同域下的内容),因为我们在日常的项目开发时会不可避免的需要进行跨域操作,所以跨域能力也算是前端工程师的基本功之一。  和大多数跨域的解决方案一样,JSONP也是我的选择,可是某天PM的需求变了,某功能需要改成支持POST,因为传输的数据量比较大,GET形式搞不定。所以折腾了下闻名已久的CORS(跨域资源共享,Cross-Origin Resource Sharing),这边文章也就是折腾期间的小记与总结。•CORS能做什么:正常使用AJAX会需要正常考虑跨域问题,所以伟大的程序员们又折腾出了一系列跨域问题的解决方案,如JSONP、flash、ifame、xhr2等等。• CORS的原理:CORS定义一种跨域访问的机制,可以让AJAX实现跨域访问。CORS 允许一个域上的网络应用向另一个域提交跨域 AJAX 请求。实现此功能非常简单,只需由服务器发送一个响应标头即可。下面我们步入正题具体详情如下所示:跨站HTTP请求(Cross-site HTTP request)是指发起请求的资源所在域不同于请求指向的资源所在域的HTTP请求。比如说,我在Web网站A(www.a.com)中通过<img>标签引入了B站的资源(www.b.com/images/1.jpg),那么A站会向B站发起一个跨站请求。这种图片资源的跨站请求是被允许的,类似的跨站请求还有CSS文件,JavaScript文件等。但是如果是在脚本中发起HTTP请求,出于安全考虑,会被浏览器限制。比如,使用 XMLHttpRequest 对象发起 HTTP 请求就必须遵守 同源策略。所谓“同源策略”是指Web应用程序只能使用 XMLHttpRequest 对象向发起源所在域内发起HTTP请求,这个请求源和请求对象必须在一个域内。举例来说,http://www.a.com,这个网址的协议是http,域名是www.a.com,端口默认是80。那么以下是它的同源情况:•http://www.a.com/index.html 同源•https://www.a.com/a.html 不同源(协议不同)•http://service.a.com/testService/test 不同源(域名不同)•http://www.b.com/index.html 不同源(域名不同)•http://www.a.com:8080/index.html 不同源(端口不同)为了开发出更强大,更丰富的Web应用,跨域请求是很常见的,那么如何在不舍弃安全的情况下进行跨域请求呢?W3C推荐了一种新的机制,即跨源资源共享(Cross-Origin Resource Sharing (CORS))。跨源资源共享(CORS)是通过客户端+服务端协作声明的方式来确保请求安全的。服务端会在HTTP请求头中增加一系列HTTP请求参数(例如Access-Control-Allow-Origin等),来限制哪些域的请求和哪些请求类型可以接受,而客户端在发起请求时必须声明自己的源(Orgin),否则服务器将不予处理,如果客户端不作声明,请求甚至会被浏览器直接拦截都到不了服务端。服务端收到HTTP请求后会进行域的比较,只有同域的请求才会处理。一个使用CORS实现跨域请求的示例:客户端:function getHello() {var xhr = new XMLHttpRequest();xhr.open("post", "http://b.example.com/Test.ashx", true);xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");    // 声明请求源xhr.setRequestHeader("Origin", "http://a.example.com");xhr.onreadystatechange = function () {if (xhr.readyState == 4 && xhr.status == 200) {var responseText = xhr.responseText;console.info(responseText);}}xhr.send();} 服务端:public class Test : IHttpHandler{public void ProcessRequest(HttpContext context){context.Response.ContentType = "text/plain";// 声明接受所有域的请求context.Response.AddHeader("Access-Control-Allow-Origin", "*");context.Response.Write("Hello World");}public bool IsReusable{get{return false;}}}在Web API中启用跨域访问CORS是服务端和客户端协作声明来确保请求安全的,因此,如果需要在Web API中启用CORS也需要进行相应配置。好在微软的ASP.NET团队提供了官方的支持跨域的解决方案,只需要在NuGet中添加即可。然后在App_Start/WebApiConfig.cs进行如下配置即可实现跨域访问:public static class WebApiConfig{public static void Register(HttpConfiguration config){// Web API 配置和服务// 将 Web API 配置为仅使用不记名令牌身份验证。config.SuppressDefaultHostAuthentication();config.Filters.Add(new HostAuthenticationFilter(OAuthDefaults.AuthenticationType));// Web API 路由config.MapHttpAttributeRoutes();config.Routes.MapHttpRoute(name: "DefaultApi",routeTemplate: "api/{controller}/{id}",defaults: new { id = RouteParameter.Optional });// 允许Web API跨域访问EnableCrossSiteRequests(config);config.Formatters.JsonFormatter.SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/html"));}private static void EnableCrossSiteRequests(HttpConfiguration config) {var cors = new EnableCorsAttribute(origins: "*",headers: "*",methods: "*");config.EnableCors(cors);}}由于IE10以下浏览器不支持CORS,所以目前在国内CORS并不是主流的跨域解决方案,但是随着windows 10的发布,IE的逐渐衰落,可以预见,在不远的将来CORS将成为跨域的标准解决方案。以上所述是小编给大家介绍的JS跨域解决方案之使用CORS实现跨域,希望对大家有所帮助!

本文实例讲述了js获取客户端操作系统类型的方法。分享给大家供大家参考,具体如下:<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN""http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8" /><title>js判断客户端操作系统类型</title></head><body><script language="javascript">function detectOS() { var sUserAgent = navigator.userAgent; var isWin = (navigator.platform == "Win32") || (navigator.platform == "Windows"); var isMac = (navigator.platform == "Mac68K") || (navigator.platform == "MacPPC") || (navigator.platform == "Macintosh") || (navigator.platform == "MacIntel"); if (isMac) return "MacOS"; var isUnix = (navigator.platform == "X11") && !isWin && !isMac; if (isUnix) return "Unix"; var isLinux = (String(navigator.platform).indexOf("Linux") > -1); if (isLinux) return "Linux"; if (isWin) { var isWin2K = sUserAgent.indexOf("Windows NT 5.0") > -1 || sUserAgent.indexOf("Windows 2000") > -1; if (isWin2K) return "Windows2000"; var isWinXP = sUserAgent.indexOf("Windows NT 5.1") > -1 || sUserAgent.indexOf("Windows XP") > -1; if (isWinXP) return "WindowsXP"; var isWin2003 = sUserAgent.indexOf("Windows NT 5.2") > -1 || sUserAgent.indexOf("Windows 2003") > -1; if (isWin2003) return "Windows2003"; var isWinVista= sUserAgent.indexOf("Windows NT 6.0") > -1 || sUserAgent.indexOf("Windows Vista") > -1; if (isWinVista) return "Windows Vista"; var isWin7 = sUserAgent.indexOf("Windows NT 6.1") > -1 || sUserAgent.indexOf("Windows 7") > -1; if (isWin7) return "Windows7"; } return "other";}document.writeln("您的操作系统是:" + detectOS());</script></body></html>PS:顺便一提的是本站在线工具的IP归属地查询工具中也使用了上述方法来判断进行用户操作系统类型判断。如下:IP地址归属地在线查询工具:http://tools.jb51.net/aideddesign/ipcha顺便再为大家推荐几款比较实用的JS在线格式化工具,相信在以后的开发中会经常用到:C语言风格/HTML/CSS/json代码格式化美化工具:http://tools.jb51.net/code/ccode_html_css_json在线JavaScript代码美化、格式化工具:http://tools.jb51.net/code/jsJavaScript代码美化/压缩/格式化/加密工具:http://tools.jb51.net/code/jscompress在线JSON代码检验、检验、美化、格式化工具:http://tools.jb51.net/code/jsonjson代码在线格式化/美化/压缩/编辑/转换工具:http://tools.jb51.net/code/jsoncodeformat更多关于JavaScript相关内容可查看本站专题:《JavaScript中ajax操作技巧总结》、《JavaScript中json操作技巧总结》、《JavaScript切换特效与技巧总结》、《JavaScript查找算法技巧总结》、《JavaScript动画特效与技巧汇总》、《JavaScript错误与调试技巧总结》、《JavaScript数据结构与算法技巧总结》、《JavaScript遍历算法与技巧总结》及《JavaScript数学运算用法总结》希望本文所述对大家JavaScript程序设计有所帮助。

今日就发个丑丑的时钟,老实说 有没有什么调试canvas的工具,老是要在浏览器刷新查看效果,好累啊~ (┬_┬)代码: <!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title>Document</title> <style> body{ background: #eee; } canvas{ background: #fff; } </style></head><body> <canvas width="800" height="800">你浏览器不支持,请升级...</canvas> <audio id="audio" src="1.wav"></audio> <script> var oAudio=document.getElementById("audio"); var oCas=document.getElementsByTagName("canvas")[0]; var cas=oCas.getContext("2d"); oAudio.ontimeupdate=function(){ if(oAudio.currentTime>0.1){ this.pause(); } } /*渐变颜色*/ var color=cas.createRadialGradient(400,400,10,400,400,200); color.addColorStop(0,"#f1f4f5"); color.addColorStop(1,"#c5c6c7"); setInterval(function(){ oAudio.currentTime=0; oAudio.play(); cas.clearRect(0,0,800,800); /*画圆框*/ cas.lineWidth=3; cas.shadowColor="#888"; cas.shadowOffsetX=1; cas.shadowOddsetY=1; cas.shadowBlur=5; cas.arc(400,400,200,0,Math.PI*2,false); cas.strokeStyle=color; cas.stroke(); /*画圆内*/ cas.fillStyle=color; cas.fill(); /*画时刻*/ drawTime(); function drawTime(){ var len=8; var len1=16; cas.strokeStyle="#7f7f7f"; cas.shadowOffsetX=0; cas.shadowOddsetY=0; cas.shadowBlur=0; cas.beginPath(); for(var i=0;i<60;i++){ if(i%5==0){ cas.moveTo(400+Math.cos(i*6*Math.PI/180)*200,400+Math.sin(i*6*Math.PI/180)*200); cas.lineTo(400+(200-len1)*Math.cos(i*6*Math.PI/180),400+(200-len1)*Math.sin(i*6*Math.PI/180)); }else{ cas.moveTo(400+Math.cos(i*6*Math.PI/180)*200,400+Math.sin(i*6*Math.PI/180)*200); cas.lineTo(400+(200-len)*Math.cos(i*6*Math.PI/180),400+(200-len)*Math.sin(i*6*Math.PI/180)); } } cas.stroke(); } /*画时针*/ var date=new Date(); var h=date.getHours(); var m=date.getMinutes(); var s=date.getSeconds(); /*时针*/ needle(h*5+5*m/60,100,"#579ec5"); /*分针*/ needle(m,130,"#5e717c"); /*秒针*/ needle(s,150,"#1d1e1e"); /*圆的中心点*/ cas.fillStyle="#858384"; cas.beginPath(); cas.arc(400,400,5,0,2*Math.PI,true); cas.shadowOffsetX=1; cas.shadowOddsetY=1; cas.shadowBlur=5; cas.fill(); },1000); /*时针的函数*/ function needle(t,len,color){ var angle=Math.PI/180; cas.beginPath(); cas.strokeStyle=color; cas.moveTo(400,400); cas.lineTo(400+len*Math.cos((t*6-90)*angle),400+len*Math.sin((t*6-90)*angle)); cas.stroke(); } </script></body></html>这个钟重点不在怎么画,在三角函数,三角函数的使用与角度息息相关,Math.PI是π,Math.sin(),Math.cos()它们都是接受弧度的,所以要 把角度转换成弧度,在画钟前要先判断时钟的条件,把圆分成60份,每一份代表一个刻度,还有在圆的坐标是数学里的正方向为准的,所以 需要把开始坐标调一下,减个90度就可以和时钟的开始位置一样了。 在学canvas前一定要把以前遗忘的数学函数复习复习一下,不是一些复杂的算数就无法做了,canvas的学习就是坐标的不断确认的,然后连成线 最后画成图,这与数学里的点到线,线到面一样的道理。 上面的代码不难都是使用线条画的,就是重复的使用画线函数和填充颜色。噢~还有外加了一个声频标签使用,达到时钟的声音    滴答滴答滴答~以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

看到一个问题:定时更新GridView的某一列中的状态文本。马上就有了思路:GridView最后会生成表格,所以我们在页面中通过Ajax更新表格的列,从而达到ajax更新GridView的效果。具体实现:准备一个xml文件,用于存储要更新的数据,在页面中启动一个定时器,每隔5秒钟调用一个函数,函数里边通过$.ajax获取xml中的数据,解析xml,遍历表格行,匹配要更新的数据,更新。getuserlist.xml定义一个UserList的根节点,下边每个UserItem对应一条数据,UID可以理解成主键,UStatus是最新的状态。<?xml version="1.0" encoding="utf-8" ?><UserList><UserItem><UID>1</UID><UStatus>关闭</UStatus></UserItem><UserItem><UID>2</UID><UStatus>关闭</UStatus></UserItem><UserItem><UID>3</UID><UStatus>开放</UStatus></UserItem></UserList>test.html具体的逻辑都写到这里边了。<html> <head> <title>Ajax Update Table Column</title> <script src="jquery-1.3.1.min.js" type="text/javascript"></script> <script type="text/javascript"> window.onload=function(){ //每隔5秒检查一下数据 window.setInterval(checkStatus,5000); }; //检查数据 function checkStatus(){ //ajax请求数据 $.ajax({ //换成你的文件,构造xml格式的数据就行了 url: 'getuserlist.xml', //请求类型 type: 'GET', //数据格式 dataType: 'xml', //超时时间:1秒 timeout: 2000, //加载数据发生错误 error:function (XMLHttpRequest, textStatus, errorThrown) { alert("XMLHttpRequest="+XMLHttpRequest.responseText+"\ntextStatus="+textStatus+"\nerrorThrown="+errorThrown); }, //成功加载数据 success: function(xml){//遍历表格的行,需要给表格定义一个ID $("#userListTable tr").each(function(){//获取行的第一列,这里边保存了XML中对应的UID信息 var trID=$(this).find("td").eq(0).text();//数据的新状态 var trStatus="";//遍历xml中的UserItem $(xml).find("UserList > UserItem").each(function(){//获取UID和UStatus的值 var uid = $(this).find("UID").text(); var ustatus = $(this).find("UStatus").text();//比对当前行的ID和UID,如果相等,给数据的新状态赋值 if(trID==uid){ trStatus=ustatus; } });//如果数据的新状态不为空,则更新单元格中现实的文本 if(trStatus!=""){ $(this).find("td").eq(2).text(trStatus); } }); } }); } </script> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> </head> <body><!--这个表格有三列ID:数据的ID,相当于主键,用于从xml中查询新数据Name:只是显示Status:要更新的列--> <table border="1" id="userListTable"> <tr><th>ID</th><th>Name</th><th>Status</th></tr> <tr><td>1</td><td>张三</td><td>开放</td></tr> <tr><td>2</td><td>李四</td><td>开放</td></tr> <tr><td>3</td><td>王五</td><td>开放</td></tr> </table> </body></html>最后将所需文件放到一个可以浏览的站点下边,打开test.html。等待5秒钟,就可以看到效果了。因为IE的问题,直接在文件夹下打开会出现不能解析xml文件(parsererror)的问题,所以建议放到可以运行的站点下边,或者用别的浏览器打开。PS:GridView 是 DataGrid的后继控件,在 framework 2 中,虽然还存在DataGrid,但是GridView已经走上了历史的前台,取代DataGrid的趋势已是势不可挡。GridView和DataGrid功能相似,都是在web页面中显示数据源中的数据,将数据源中的一行数据,也就是一条记录,显示为在web页面上输出表格中的一行。GridView相对于DataGrid来说,具有如下优势,功能上更加丰富,因为提供了智能标记面板(也就是show smart tag)更加易用方便,常用的排序、分页、更新、删除等操作可以零代码实现!具有PagerTemplate属性,可以自定义用户导航页面,也就是说分页的控制更加随心所欲。GridView和DataGrid在事件模型上也多有不同之处,DataGrid控件引发的都是单个事件,而GridView控件会引发两个事件,一个在操作前发生,一个在操作后发生,操作前的事件多位***ing事件,操作后的事件多位***ed事件,比如Sorting 事件和sorted 事件,RowDeleting和RowDeleted事件。Listview和Gridview的刷新界面的方式是调用adapter.notifyDataSetChanged()进行界面刷新。但是此方法有其弊端,他是将界面中的数据全部刷新一遍,不论数据有没有变化。

本文实例讲述了Jquery日期选择datepicker插件用法。分享给大家供大家参考。具体如下:1、首先将Jquery中的datepicker插件中的相关属性值改成中文的:$.datepicker.regional['zh-CN'] = { clearText: '清除', clearStatus: '清除已选日期', closeText: '关闭', closeStatus: '不改变当前选择', prevText: '<上月', prevStatus: '显示上月', prevBigText: '<<', prevBigStatus: '显示上一年', nextText: '下月>', nextStatus: '显示下月', nextBigText: '>>', nextBigStatus: '显示下一年', currentText: '今天', currentStatus: '显示本月', monthNames: ['一月','二月','三月','四月','五月','六月', '七月','八月','九月','十月','十一月','十二月'], monthNamesShort: ['一','二','三','四','五','六', '七','八','九','十','十一','十二'], monthStatus: '选择月份', yearStatus: '选择年份', weekHeader: '周', weekStatus: '年内周次', dayNames: ['星期日','星期一','星期二','星期三','星期四','星期五','星期六'], dayNamesShort: ['周日','周一','周二','周三','周四','周五','周六'], dayNamesMin: ['日','一','二','三','四','五','六'], dayStatus: '设置 DD 为一周起始', dateStatus: '选择 m月 d日, DD', dateFormat: 'yy-mm-dd', firstDay: 1, initStatus: '请选择日期', isRTL: false};$.datepicker.setDefaults($.datepicker.regional['zh-CN']); 2、html页面中有两个日期输入框,分别为起始日期和结束日期:<label for="start-datepicker">起始日期:</label> <input type="text" class="datepicker test-image-datepicker" id="start-datepicker" size="15" />  <label for="end-datepicker">结束日期:</label> <input type="text" class="datepicker test-image-datepicker" id="end-datepicker" size="15" />3、调用修改后的datepicker插件:var $start_date_value = "2012年1月1日"; // TODO 改成可以配置的var $end_date_value = new Date();// When document has loaded, initialize pagination and form $(document).ready(function(){ $(".imagezz").click($test_image_check_box_click); $( ".test-image-datepicker" ).datepicker({ changeMonth: true, changeYear: true, showOn: "both", buttonImage: "images/calendar.gif", buttonImageOnly: true, showButtonPanel: true, onSelect: function(dateText, inst){ if ($(this).attr("id") == "start-datepicker") { $start_date_value = dateText; } if ($(this).attr("id") == "end-datepicker") { $end_date_value = dateText; } //下面可以写一些根据日期变化引起页面相关部分修改的函数 //...... }});$(".test-image-datepicker").datepicker("option", "dateFormat", "yy年mm月dd日");$('.test-image-datepicker').attr("readonly","readonly");$("#start-datepicker").datepicker("setDate",$start_date_value);$("#end-datepicker").datepicker("setDate",$end_date_value);datepicker其余选项及方法详见:http://api.jqueryui.com/datepicker/希望本文所述对大家的jQuery程序设计有所帮助。

焦点访谈

最新最热的文章

更多 >

COPYRIGHT (©) 2017 Copyright ©2017 888真人 网站地图

联系我们

827570882

扫描二维码分享到微信