Skip to content

Commit 926e321

Browse files
committed
【feature】openlayers VectorTileSuperMapRest MapboxStyles 支持传入自定义请求头
1 parent 9353462 commit 926e321

File tree

4 files changed

+169
-72
lines changed

4 files changed

+169
-72
lines changed

src/openlayers/overlay/VectorTileSuperMapRest.js

Lines changed: 49 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ import decryptTileUtil from '@supermapgis/tile-decryptor';
3434
* @param {(string|Object)} [options.attributions='Tile Data <span>© <a href='http://support.supermap.com.cn/product/iServer.aspx' target='_blank'>SuperMap iServer</a></span> with <span>© <a href='https://iclient.supermap.io' target='_blank'>SuperMap iClient</a></span>'] - 版权描述信息。
3535
* @param {Object} [options.format] - 瓦片的要素格式化。
3636
* @param {boolean} [options.withCredentials] - 请求是否携带 cookie。
37+
* @param {Object} [options.headers] - 请求头。
3738
* @param {boolean|Function} [options.decrypt] - 瓦片解密。如果是 true 表示用内置的解密方法, 如 decrypt: true;如果是function 则是自定义解密如 decrypt: function ({ key, bytes })。
3839
* @param {Function} [options.decryptCompletedFunction] - 解密完成后触发。如 decryptCompletedFunction(completeData)。
3940
* @extends {ol.source.VectorTile}
@@ -77,6 +78,7 @@ export class VectorTileSuperMapRest extends VectorTile {
7778
});
7879
var me = this;
7980
me.withCredentials = options.withCredentials;
81+
me.headers = options.headers || {};
8082
me._tileType = options.tileType || 'ScaleXY';
8183
this.vectorTileStyles = new VectorTileStyles();
8284
this._initialized(options);
@@ -165,9 +167,9 @@ export class VectorTileSuperMapRest extends VectorTile {
165167
var regHeight = new RegExp('(^|\\?|&)' + 'height' + '=([^&]*)(\\s|&|$)');
166168
var width = Number(tileUrl.match(regWidth)[2]);
167169
var height = Number(tileUrl.match(regHeight)[2]);
168-
170+
var me = this;
169171
tile.setLoader(function (extent, resolution, projection) {
170-
FetchRequest.get(tileUrl)
172+
FetchRequest.get(tileUrl, null, {headers:me.headers})
171173
.then(function (response) {
172174
if (tile.getFormat() instanceof GeoJSON) {
173175
return response.json();
@@ -251,45 +253,50 @@ export class VectorTileSuperMapRest extends VectorTile {
251253
xhr.responseType = 'arraybuffer';
252254
}
253255
xhr.withCredentials = me.withCredentials;
256+
for (const key in me.headers) {
257+
if (me.headers.hasOwnProperty(key)) {
258+
xhr.setRequestHeader(key, me.headers[key]);
259+
}
260+
}
254261
xhr.onload = function () {
255-
if (!xhr.status || (xhr.status >= 200 && xhr.status < 300)) {
256-
const type = format.getType();
257-
let source = void 0;
258-
if (type === 'json' || type === 'text') {
259-
source = xhr.responseText;
260-
} else if (type === 'xml') {
261-
source = xhr.responseXML;
262-
if (!source) {
263-
source = new DOMParser().parseFromString(xhr.responseText, 'application/xml');
264-
}
265-
} else if (type === 'arraybuffer') {
266-
source = xhr.response;
267-
}
268-
if (source) {
269-
source = me._decryptMvt(source);
270-
if (['4', '5'].indexOf(Util.getOlVersion()) > -1) {
271-
success.call(
272-
this,
273-
format.readFeatures(source, { featureProjection: projection }),
274-
format.readProjection(source),
275-
format.getLastExtent()
276-
);
277-
} else {
278-
success.call(
279-
this,
280-
format.readFeatures(source, {
281-
extent: extent,
282-
featureProjection: projection
283-
}),
284-
format.readProjection(source)
285-
);
286-
}
287-
} else {
288-
failure.call(this);
289-
}
262+
if (!xhr.status || (xhr.status >= 200 && xhr.status < 300)) {
263+
const type = format.getType();
264+
let source = void 0;
265+
if (type === 'json' || type === 'text') {
266+
source = xhr.responseText;
267+
} else if (type === 'xml') {
268+
source = xhr.responseXML;
269+
if (!source) {
270+
source = new DOMParser().parseFromString(xhr.responseText, 'application/xml');
271+
}
272+
} else if (type === 'arraybuffer') {
273+
source = xhr.response;
274+
}
275+
if (source) {
276+
source = me._decryptMvt(source);
277+
if (['4', '5'].indexOf(Util.getOlVersion()) > -1) {
278+
success.call(
279+
this,
280+
format.readFeatures(source, { featureProjection: projection }),
281+
format.readProjection(source),
282+
format.getLastExtent()
283+
);
284+
} else {
285+
success.call(
286+
this,
287+
format.readFeatures(source, {
288+
extent: extent,
289+
featureProjection: projection
290+
}),
291+
format.readProjection(source)
292+
);
293+
}
290294
} else {
291-
failure.call(this);
295+
failure.call(this);
292296
}
297+
} else {
298+
failure.call(this);
299+
}
293300
}.bind(this);
294301
xhr.onerror = function () {
295302
failure.call(this);
@@ -304,7 +311,10 @@ export class VectorTileSuperMapRest extends VectorTile {
304311
let style = options.style;
305312
if (Object.prototype.toString.call(options.style) == '[object String]') {
306313
var url = SecurityManager.appendCredential(options.style);
307-
const response = await FetchRequest.get(url, null, { withCredentials: options.withCredentials })
314+
const response = await FetchRequest.get(url, null, {
315+
withCredentials: options.withCredentials,
316+
headers: options.headers
317+
});
308318
style = await response.json();
309319
}
310320
this._fillByStyleJSON(style, options.source);

src/openlayers/overlay/vectortile/MapboxStyles.js

Lines changed: 41 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ import Text from 'ol/style/Text';
3434
* @param {ol.Map} [options.map] - Openlayers 地图对象,仅用于面填充样式,若没有面填充样式可不填。
3535
* @param {ol.StyleFunction} [options.selectedStyle] -选中样式 Function。
3636
* @param {boolean} [options.withCredentials] - 请求是否携带 cookie。
37+
* @param {Object} [options.headers] - 请求头。
3738
* @example
3839
* var mbStyle = new MapboxStyles({
3940
url: url,
@@ -73,6 +74,7 @@ export class MapboxStyles extends Observable {
7374
);
7475
this.resolutions = options.resolutions;
7576
this.withCredentials = options.withCredentials;
77+
this.headers = options.headers;
7678
this.selectedObjects = [];
7779
this.selectedStyle =
7880
options.selectedStyle ||
@@ -252,7 +254,7 @@ export class MapboxStyles extends Observable {
252254
}, 0);
253255
} else {
254256
var url = SecurityManager.appendCredential(style);
255-
FetchRequest.get(url, null, { withCredentials: this.withCredentials })
257+
FetchRequest.get(url, null, { withCredentials: this.withCredentials, headers: this.headers })
256258
.then(response => response.json())
257259
.then(mbStyle => {
258260
this._mbStyle = mbStyle;
@@ -271,32 +273,48 @@ export class MapboxStyles extends Observable {
271273
this._mbStyle.sprite = this._mbStyle.sprite.replace('@2x', '');
272274
const spriteUrl = this._toSpriteUrl(this._mbStyle.sprite, this.path, sizeFactor + '.json');
273275
FetchRequest.get(SecurityManager.appendCredential(spriteUrl), null, {
274-
withCredentials: this.withCredentials
276+
withCredentials: this.withCredentials,
277+
headers: this.headers
275278
})
276-
.then(response => response.json())
277-
.then(spritesJson => {
278-
this._spriteData = spritesJson;
279-
this._spriteImageUrl = SecurityManager.appendCredential(
280-
this._toSpriteUrl(this._mbStyle.sprite, this.path, sizeFactor + '.png')
281-
);
282-
this._spriteImage = null;
279+
.then((response) => response.json())
280+
.then((spritesJson) => {
281+
this._spriteData = spritesJson;
282+
this._spriteImageUrl = SecurityManager.appendCredential(
283+
this._toSpriteUrl(this._mbStyle.sprite, this.path, sizeFactor + '.png')
284+
);
285+
this._spriteImage = null;
286+
287+
var xhr = new XMLHttpRequest();
288+
xhr.responseType = 'blob';
289+
xhr.addEventListener('loadend',(e) => {
290+
var data = e.target.response;
291+
if (data !== undefined) {
283292
const img = new Image();
284-
img.crossOrigin = this.withCredentials ? 'use-credentials' : 'anonymous';
285-
img.onload = () => {
286-
this._spriteImage = img;
287-
this._initStyleFunction();
288-
};
289-
img.onerror = () => {
290-
this._spriteImage = null;
291-
this._initStyleFunction();
292-
};
293-
img.src = this._spriteImageUrl;
294-
})
295-
.catch( err => {
296-
console.log(err);
293+
img.src = URL.createObjectURL(data);
294+
this._spriteImage = img;
295+
} else {
297296
this._spriteImage = null;
298-
this._initStyleFunction();
297+
}
298+
this._initStyleFunction();
299+
});
300+
xhr.addEventListener('error', () => {
301+
this._spriteImage = null;
302+
this._initStyleFunction();
299303
});
304+
xhr.open('GET', this._spriteImageUrl);
305+
for (const key in this.headers) {
306+
if (this.headers.hasOwnProperty(key)) {
307+
xhr.setRequestHeader(key, this.headers[key]);
308+
}
309+
}
310+
xhr.withCredentials = this.withCredentials;
311+
xhr.send();
312+
})
313+
.catch((err) => {
314+
console.log(err);
315+
this._spriteImage = null;
316+
this._initStyleFunction();
317+
});
300318
} else {
301319
this._initStyleFunction();
302320
}

test/openlayers/overlay/VectorTileSuperMapRestMapboxstyleSpec.js

Lines changed: 53 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -33,16 +33,16 @@ describe('openlayers_VectorTileSuperMapRest_mapboxStyle', () => {
3333
projection: 'EPSG:4326',
3434
})
3535
});
36-
spyOn(FetchRequest, 'get').and.callFake((testUrl, params, options) => {
37-
if (testUrl.indexOf("vectorstyles") > 0) {
38-
expect(testUrl).toBe(url + "/tileFeature/vectorstyles?type=MapBox_GL&styleonly=true");
39-
return Promise.resolve(new Response(JSON.stringify(vectorstylesEscapedJson)));
40-
} else if (testUrl.indexOf("sprite.json") > 0) {
41-
return Promise.resolve(new Response(JSON.stringify(spriteEscapedJson)));
42-
};
43-
return null;
36+
// spyOn(FetchRequest, 'get').and.callFake((testUrl, params, options) => {
37+
// if (testUrl.indexOf("vectorstyles") > 0) {
38+
// expect(testUrl).toBe(url + "/tileFeature/vectorstyles?type=MapBox_GL&styleonly=true");
39+
// return Promise.resolve(new Response(JSON.stringify(vectorstylesEscapedJson)));
40+
// } else if (testUrl.indexOf("sprite.json") > 0) {
41+
// return Promise.resolve(new Response(JSON.stringify(spriteEscapedJson)));
42+
// };
43+
// return null;
4444

45-
});
45+
// });
4646

4747

4848
});
@@ -121,4 +121,48 @@ describe('openlayers_VectorTileSuperMapRest_mapboxStyle', () => {
121121
map.addLayer(vectorLayer);
122122

123123
});
124+
125+
it('initialize_headers', (done) => {
126+
spyOn(FetchRequest, 'get').and.callFake((testUrl, params, options) => {
127+
if (testUrl.indexOf("vectorstyles") > 0) {
128+
expect(options.headers).not.toBeNull();
129+
expect(options.headers.appToken).toBe('test');
130+
expect(testUrl).toBe(url + "/tileFeature/vectorstyles?type=MapBox_GL&styleonly=true");
131+
return Promise.resolve(new Response(JSON.stringify(vectorstylesEscapedJson)));
132+
}
133+
return null;
134+
});
135+
136+
var format = new MVT({
137+
featureClass: Feature
138+
});
139+
vectorLayer = new VectorTileLayer({
140+
//设置避让参数
141+
declutter: true,
142+
source: new VectorTileSuperMapRest({
143+
style: url + "/tileFeature/vectorstyles?type=MapBox_GL&styleonly=true",
144+
projection: 'EPSG:4326',
145+
source: 'California',
146+
format: format,
147+
headers:{'appToken':'test'}
148+
})
149+
});
150+
spyOn(vectorLayer.getSource(), 'tileLoadFunction').and.callFake((tile)=>{
151+
tile.setLoader(()=>{
152+
tile.setFeatures([])
153+
})
154+
});
155+
let count = 0;
156+
vectorLayer.getSource().on('tileloadend',()=>{
157+
count++;
158+
console.log(count)
159+
if(count === 4){
160+
expect(vectorLayer.getSource().tileLoadFunction.calls.count()).toEqual(4);
161+
done();
162+
}
163+
164+
})
165+
map.addLayer(vectorLayer);
166+
167+
});
124168
});

test/openlayers/overlay/vectortile/MapboxStylesSpec.js

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ describe("openlayers_MapboxStyles", () => {
5656
if (testUrl.indexOf("vectorstyles") > 0) {
5757
expect(testUrl).toBe(url + "/tileFeature/vectorstyles?type=MapBox_GL&styleonly=true");
5858
return Promise.resolve(new Response(JSON.stringify(vectorstylesEscapedJson)));
59-
} else if (testUrl.indexOf("sprite.json") > 0) {
59+
} else if (testUrl.indexOf("sprite.json") > 0 || testUrl.indexOf("[email protected]") > 0) {
6060
return Promise.resolve(new Response(JSON.stringify(spriteEscapedJson)));
6161
}
6262
return null;
@@ -254,4 +254,29 @@ describe("openlayers_MapboxStyles", () => {
254254
}
255255
});
256256
});
257+
258+
it("init_Style_headers", done => {
259+
spyOn(XMLHttpRequest.prototype, 'send').and.callThrough();
260+
spyOn(XMLHttpRequest.prototype, 'setRequestHeader').and.callThrough();
261+
var style;
262+
mapboxStyles = new MapboxStyles({
263+
style: url + "/tileFeature/vectorstyles?type=MapBox_GL&styleonly=true",
264+
map: map,
265+
source: "California",
266+
headers:{'appToken':'test'}
267+
});
268+
mapboxStyles.on("styleloaded", () => {
269+
try {
270+
style = mapboxStyles.getStyleFunction();
271+
expect(style).not.toBeNull();
272+
expect(XMLHttpRequest.prototype.setRequestHeader).toHaveBeenCalledWith('appToken','test');
273+
expect(XMLHttpRequest.prototype.send).toHaveBeenCalledTimes(1);
274+
done();
275+
} catch (e) {
276+
console.log("'init_Style_headers'案例失败" + e.name + ":" + e.message);
277+
expect(false).toBeTruthy();
278+
done();
279+
}
280+
});
281+
});
257282
});

0 commit comments

Comments
 (0)