0%

前端单元测试

示例

相关工具:

karma—打开浏览器

Mocha—describe,it

chai—expect

sinon—fake

sinon-chai—calledWith

ps:如果测css 需要挂载到页面中否则没有css(创建div 将组件mount)

1.测试组件存在

1
2
3
4
5
describe('Button', () => {
it('存在.', () => {
expect(Button).to.be.ok
})
})

2.测试props传入组件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
describe('props', () => {
it('接受span属性', () => {
const div = document.createElement('div')
document.body.appendChild(div)
const Constructor = Vue.extend(Col)
const vm = new Constructor({
propsData: {
span: 1
}
}).$mount(div)
expect(vm.$el.classList.contains('cssClass')).to.equal(true)
vm.$el.remove()
vm.$destroy()
})
})

3.测试事件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
describe('Button', () => {    
it('点击 button 触发 click 事件', () => {
const Constructor = Vue.extend(Button)
const vm = new Constructor({
propsData: {
icon: 'settings',
}
}).$mount()
const callback = sinon.fake();
vm.$on('click', callback)
vm.$el.click()
expect(callback).to.have.been.called
})
})

4.测试CSS样式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
describe('Row', () => {
it('接受gutter属性', (done) => {
Vue.component('g-row', Row)
Vue.component('g-col', Col)
const div = document.createElement('div')
document.body.appendChild(div)
div.innerHTML = `
<g-row gutter="20">
<g-col span="12"></g-col>
<g-col span="12"></g-col>
</g-row>
`
const vm = new Vue({
el: div
})
setTimeout(() => {
const cols = vm.$el.querySelectorAll('.col')
const rows = vm.$el.querySelector('.row')
expect(getComputedStyle(cols[0]).paddingLeft).to.eq('10px')
expect(getComputedStyle(cols[1]).paddingRight).to.eq('10px')
expect(getComputedStyle(rows).marginRight).to.eq('-10px')
expect(getComputedStyle(rows).marginLeft).to.eq('-10px')
vm.$el.remove()
vm.$destroy()
//done()防止执行完主线程自动关闭浏览器不执行队列中的settimeout
done()
}, 0)
})
})

由 ArcMap 发布

DTM 数据集配置完成后,将其作为 ArcMap 中的缓存影像服务进行发布。

  1. 启动 ArcMap。

  2. 如果您还没有 GIS 服务器发布方连接,可在目录树中创建一个。

  3. 连接到包含栅格数据集的地理数据库或将连接映射到包含 TIFF 的文件夹。

  4. 右键单击 DTM,然后单击共享为影像服务。

  5. 选择发布服务,然后单击下一步。

  6. 选择您希望接收发布内容的目标 GIS 服务器,输入影像服务的名称,然后单击下一步。

  7. 指定 GIS 服务器上您希望用来存储影像服务的文件夹。

  8. 单击继续打开服务编辑器。

  9. 您可以为服务设置不同的参数和值,但必须在服务编辑器中设置所需的以下值:

    1. 在功能面板上,选择影像。

    2. 在缓存面板上,选择以下全部内容:

      • 为绘制此影像服务选项选择使用缓存中的切片。
      • 选择 ArcGIS Online/Bing 地图/Google 地图作为切片方案。
      • 指定适合您的数据的细节层次。
      • 选择发布服务时自动构建缓存选项。
  10. 打开缓存 > 高级设置面板,设置以下值:

    1. 指定 GIS 服务器上缓存目录的位置。

    2. 将要缓存的感兴趣区域设置为数据集全图范围。

    3. 选择 LERC 作为切片格式。

    4. 默认压缩值 0.5 适合世界影像服务,但大多数情况下,您将为小得多的地区(例如,城市或地区)发布高程数据。在这些情况下,将压缩设置为 0.1。

  11. 将描述、汇总和标签添加到项目描述面板中。

  12. 如果发布到联合的 GIS 服务器上,请打开共享 面板,与门户或任何人共享服务。

前言

记录一下跨域的一些学习笔记吧。

跨域是啥

JS处于安全方面考虑,因为同源策略限制,不允许调用不同域的对象,不同域的之间相互请求资源就叫”跨域”

怎么算不同域

看表看表,从其他地方扒过来的。。。。
跨域表
就是看域名地址、协议、域名、端口必须一样才可以,不包括IP地址。
要是协议和端口都不一样,前端没有办法

同源策略及其限制是啥

同源策略限制从一个源加载的文档或脚本如何与来自另一个源的资源进行交互。这是一个用于隔离潜在恶意文件的关键的安全机制。它的存在可以保护用户隐私信息,防止身份伪造等(读取Cookie)。

同源策略限制内容有:

  • Cookie、LocalStorage、IndexedDB 等存储性内容
  • DOM节点
  • AJAX 请求不能发送

但是以下标签是允许跨域加载资源:

  • <img src="">
  • <link href="">
  • <script src="">
  • <iframe src="">

处理跨域方法

一、 JSONP(JSON with Padding)

script 标签的src属性可以跨域引用文件,jsonp是请求之后后台包装好一段json,并且把数据放在一个callback函数,返回一个js文件,动态引入这个文件,下载完成js之后,会去调用这个callback,通过这样访问数据。

在换句话说:

1.我们用ajax无法跨域访问资源

2.发现script标签的src属性没有这个限制

3.那我们现在写个url,加上需要的一些参数,比如?callback=foo,告诉服务器本地要用返回数据的函数叫啥。

1
2
3
let foo = function(data) {
//do something
}

4.服务端实现这个功能:根据这个url里带的参数,生成一个js文件,就是调用一下这个函数,生成这个函数需要的数据对象传传入,像下面这样:

1
2
3
4
foo({
"key1": "value1",
"key2": "value2"
});

5.然后呢,客户端把这个url放到script标签的src属性里,就是相当于引入了上面调用函数的这段代码。

无非就是函数的声明在客户端,通过script标签src属性引入外部js文件执行函数,得到结果。这样服务器就需要动态的生成js文件。很多框架吧jsonp和ajax封装在一起方便使用,但是要知道他们本质是不同的东西。网上扒了一个图。。。应该能看出点东西吧

ajax

1.JSONP和AJAX对比

AJAX属于同源策略,JSONP属于非同源策略(跨域请求)。

2.JSONP优缺点

JSONP优点是兼容性好,可用于解决主流浏览器的跨域数据访问的问题。缺点是仅支持get方法具有局限性。

二、CORS

CORS是一个W3C标准,全称是”跨域资源共享”(Cross-origin resource sharing)。它允许浏览器向跨源(协议 + 域名 + 端口)服务器,发出XMLHttpRequest请求,从而克服了AJAX只能同源使用的限制。

浏览器将CORS请求分为简单请求(simple request)和非简单请求(not-so-simple request)

简单请求满足以下两点:

1) 请求方法是以下三种方法之一:
HEAD
GET
POST
2)HTTP的头信息不超出以下几种字段:
Accept
Accept-Language
Content-Language
Last-Event-ID
Content-Type:只限于三个值application/x-www-form-urlencoded、multipart/form-data、text/plain

  • 对于简单请求:需要在服务器响应头中添加Access-Control-Allow-Origin:*表示允许任意域名访问某个资源,当然也可以是一个完整的域名。如果服务器没有设置返回带有特殊头部的数据,简单请求GET或者POST请求仍然会发送,服务器的数据也会返回,但是浏览器会阻止Javascript获取这次请求。

  • 对于非简单请求:会在正式通信之前,增加一次HTTP查询请求,称为”预检”请求(preflight),发送一个OPTIONS请求到服务器。如果OPTIONS的请求,服务器没有做出适当的返回,后面真实的请求将不会发送。

来认识一下头信息(请求和响应)

  1. Access-Control-Allow-Origin

    由服务器返回,*允许表示任意域名,或者一个完整的域名名字。

如果你需要客户端传递验证信息到头部(比如:cookies)。这个值不能为 * —— 必须为完整的域名(这点很重要)。

  1. Access-Control-Allow-Credentials

    这个头部信息只会在服务器支持通过cookies传递验证信息的返回数据里。它的值只有一个就是 true。跨站点带验证信息时,服务器必须要争取设置这个值,服务器才能获取到用户的cookie。

  2. Access-Control-Allow-Headers

    提供一个逗号分隔的列表表示服务器支持的请求数据类型。假如你使用自定义头部(比如:x-authentication-token 服务器需要在返回OPTIONS请求时,要把这个值放到这个头部里,否则请求会被阻止)。

  3. Access-Control-Allow-Methods

    一个逗号分隔的列表,表明服务器支持的请求类型(比如:GET, POST)

  4. Origin

    这个头部信息,属于请求数据的一部分。这个值表明这个请求是从浏览器打开的哪个域名下发出的。出于安全原因,浏览器不允许你修改这个值。

  1. Access-Control-Max-Age

    该字段可选,用来指定本次预检请求的有效期,单位为秒。在有效期间,不用发出另一条预检请求。

CORS优缺点

CORS要求浏览器(>IE10)和服务器的同时支持,是跨域的根本解决方法,由浏览器自动完成。优点在于功能更加强大支持各种HTTP Method,缺点是兼容性不如JSONP。对于开发者来说,CORS通信与同源的AJAX通信没有差别,代码完全一样,只需要在服务器端加一些头信息即可

三、WebSocket

网上扒的、放着先后面再看。。

Websocket是HTML5的一个持久化的协议,它实现了浏览器与服务器的全双工通信,同时也是跨域的一种解决方案。WebSocket和HTTP都是应用层协议,都基于 TCP 协议。但是 WebSocket 是一种双向通信协议,在建立连接之后,WebSocket 的 server 与 client 都能主动向对方发送或接收数据。同时,WebSocket 在建立连接时需要借助 HTTP 协议,连接建立好了之后 client 与 server 之间的双向通信就与 HTTP 无关了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
//前端代码:
<div>user input:<input type="text"></div>
<script src="./socket.io.js"></script>
<script>
var socket = io('http://www.domain2.com:8080');
// 连接成功处理
socket.on('connect', function() {
// 监听服务端消息
socket.on('message', function(msg) {
console.log('data from server: ---> ' + msg);
});
// 监听服务端关闭
socket.on('disconnect', function() {
console.log('Server socket has closed.');
});
});
document.getElementsByTagName('input')[0].onblur = function() {
socket.send(this.value);
};
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
//Nodejs socket后台:
var http = require('http');
var socket = require('socket.io');
// 启http服务
var server = http.createServer(function(req, res) {
res.writeHead(200, {
'Content-type': 'text/html'
});
res.end();
});
server.listen('8080');
console.log('Server is running at port 8080...');
// 监听socket连接
socket.listen(server).on('connection', function(client) {
// 接收信息
client.on('message', function(msg) {
client.send('hello:' + msg);
console.log('data from client: ---> ' + msg);
});
// 断开处理
client.on('disconnect', function() {
console.log('Client socket has closed.');
});
});

四、postMessage

如果两个网页不同源,就无法拿到对方的DOM。典型的例子是iframe窗口和 window.open方法打开的窗口,它们与父窗口无法通信。HTML5为了解决这个问题,引入了一个全新的API:跨文档通信 API(Cross-document messaging)。这个API为window对象新增了一个 window.postMessage 方法,允许跨窗口通信,不论这两个窗口是否同源。

postMessage方法的第一个参数是具体的信息内容,第二个参数是接收消息的窗口的源(origin),即”协议 + 域名 + 端口”。也可以设为 *,表示不限制域名,向所有窗口发送。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
//发送信息页面 
<html lang="en">
<head>
<meta charset="UTF-8">
<title>跨域请求</title>
</head>
<body>
<iframe src="http://localhost:3000/users/reg" id="frm"></iframe>
<input type="button" value="OK" onclick="run()">
</body>
</html>
<script>
function run(){
var frm=document.getElementById("frm");
frm.contentWindow.postMessage("跨域请求信息","http://localhost:3000");
}
</script>
1
2
3
4
5
//接收信息页面 http://localhost:3000/message.html
window.addEventListener("message",function(e){
//通过监听message事件,可以监听对方发送的消息。
console.log(e.data);
},false);

  • IE9 发起跨域请求要使用 XDomainRequest, 因为 IE9 下的 XMLHttpRequest 不支持跨域调用.

  • XDomainRequest 只支持 GET 和 POST method, 并且没有 response status code, 可以说是不完善的 HTTP 异步请求对象.

  • XDomainRequest 不支持指定 responseType, 使用时建议请求和返回数据格式约定为 JSON.

  • whatwg-fetch1.0+ 不支持 IE9, 是因为 IE9 的状态码不符合 fetch 规范, 而 polyfill 的目标是 polyfill 规范, 而不是做兼容.

一、X,Y生成的事件图层没有OID字段,某些工具无法直接使用,需要转成要素类。

二、 需要给某个要素类属性表添加连接表

  1. 输入必须为图层:Mosaic Layer; Raster Layer; Table View,所以需要将要素先转为图层使用方法:

    1
    arcpy.MakeFeatureLayer_management("in_memory" + "\\" + "featureclass" , "layer")
  2. 输入图层或表视图必须有 ObjectID 字段连接表不必包含 ObjectID 字段。

  3. 连接仅在会话期间有效。要保存表中属性至要素中的话,使用工具将图层保存为要素类。此方法仅适用于图层,表视图不能使用此方式进行保存。使用方法如下:

    1
    arcpy.FeatureClassToFeatureClass_conversion("layer", out_path = outputFile, out_name = FeatureName)
  4. 注意,如果不是保存为要素类,而是保存为图层文件,保存后可以看到要素数据集中的本属于连接表的字段名在要素属性表中会默认加上sheet名的前缀。
    这里我们保存为要素类,要….

    (防止后面使用该字段时出现错误,得看清楚字段名情况)

    1
    arcpy.env.qualifiedFieldNames = "UNQUALIFIED"

    下面是官方一些解释

限定的字段名(环境设置)

遵循“限定的字段名”环境的工具将使用此设置来区分限定的字段名和未限定的字段名。限定的字段名是要素类或表中的这样一些字段名称,在它们的字段名称后会附加原始要素类或表的名称。使用连接数据时,会涉及此设置。

用法说明

  • 默认限定的输出表字段命名结构为“表名.字段名”。当未限定时,输出表或要素类中的字段将始终用格式字段名命名。
  • 在限定的字段名可能超出允许的字段名宽度时,应将环境设为 UNQUALIFIED - 例如,连接 shapefile 时。Shapefile 字段将截短为八个字符。

当工具参数中包含字段映射时(“转换”工具箱的许多工具中都包括),字段名自动设置为 UNQUALIFIED,因此无需设置该环境。脚本语法

arcpy.env.qualifiedFieldNames = qualified_field_names

qualified_field_names 说明
True 输出字段名包括表名。这也可以使用 QUALIFIED 关键字设置。这是默认设置。
False 输出字段名将不包括表名。这也可以使用 UNQUALIFIED 关键字设置。

在直接使用Excel文件时,本地可以调用成功能,发布后无法找到对应路径文件。

  • 解决办法:

    使用Excel 转表,将磁盘中的表格输出到gdb中,从File类型转为Table类型。

Excel 转表

摘要

将 Microsoft Excel 文件转换为表。

用法

  • Excel 转表支持 Excel 工作簿 (.xlsx) 和 Microsoft Excel 5.0/95 工作簿 (.xls) 格式作为输入。
  • 此工具假设表数据按纵向排序。第一行用作输出表的字段名称。在验证过程中,可能会对这些字段名称重命名,以免出现任何错误或重复名称。数据间的空列将得到保留,并为其指定通用字段名(例如 field_4)。
  • 输出字段数据类型基于输入列范围内找到的值和像元格式。输出字段数据类型包括浮点型、文本和日期。如果输入列包含多个数据类型或格式类型,则输出字段的类型为文本。

语法

1
ExcelToTable_conversion (Input_Excel_File, Output_Table, {Sheet})
参数 说明 数据类型
Input_Excel_File 要转换的 Microsoft Excel 文件。 File
Output_Table 输出表。 Table
Sheet(可选) 要导入的 Excel 文件中特定工作表的名称。如果未指定,则使用工作簿中的第一个工作表。 String

代码示例

1
2
input_table = outTempTable + "/connect$"
arcpy.ExcelToTable_conversion(Input_Excel_File = outTempTable, Output_Table = "connect", Sheet = "connect")