我正试图通过websockets将在矢量层(openlayers)上创建的功能保存到postgreSQL 9.1/postGIS 2.0。我使用websocket是因为我要插入表单数据和几何图形。
我的服务器是NodeJS 0.10.12和pg模块。
我正试图将特征的几何图形转换为字符串,将其从字母和括号中去掉,然后只将数字发送到服务器。我在服务器端遇到了关于几何体的语法错误。
尽管尝试了很多东西和不同的语法,我还是无法修复它。
客户端(片段)
//create websockets
var so = new WebSocket("ws://localhost:8000");
//error report for websockets
so.onerror=function (evt)
{saveMSG.textContent = evt;}
//open websockets
so.onopen = function(){
//get geometry
var jak=map.layers[2].features[0].geometry;
//make it a string
var as=new String(jak);
//keep the numbers
var hul=as.substring(11,as.length-1);
//make it WKT
var god=hul.toString();
//send it with stringify/websockets
so.send(JSON.stringify({command: 'insertAll',
geo: god,
//send other things from the form....
以及服务器端
var packet = JSON.parse(msg.utf8Data);
switch (packet['command'])
{case 'insertAll':insertEm(packet['geo']) ;break;
//other cases here...call function according to case...
//so "insertAll" calls the following
function insertEm(geo){
//get client data, put them in place and create a string
var met="ST_GeomFromText('LINESTRING("+geo+")',900913)";
var pra=new String(met);
//connect to db and execute prepared statement
var conString = "pg://user:user@localhost:5432/myDB";
var client = new pg.Client(conString);
client.connect();
var query = client.query({name:"inser", text:"INSERT INTO pins(p_geom) values($1)", values:[pra]});
我得到错误:[error: parse error - invalid geometry] hint: '"ST"<-- parse error a position 2 within geometry']
所以我想可能是它事先准备好的陈述有错?
我已经将其切换为一个简单的查询,如:
var query = client.query("INSERT INTO pins (p_geom) values('"+pra+"')")
我得到错误
[error: syntax error at or near "LINESTRING"]
在我提出的问题的最后query.on("end", function (result) {console.log(result);connection.send(pra); client.end();});
这样我就可以看到客户端向服务器发送的内容。我得到
ST_GeomFromText('LINESTRING(2335859.0225 4725430.1340625,2378933.155 4741356.7040625)',900913)
看起来不错。。。
有什么建议吗?我真的不知道怎么解决这个问题。
使用此查询:
var query = client.query("INSERT INTO pins (p_geom) values('"+pra+"')")
你不应该引用pra
。这将引用ST_GeomFromText函数调用,您提交的查询将类似于:
var query = client.query("INSERT INTO pins (p_geom) values('ST_GeomFromText('LINESTRING(2335859.0225 4725430.1340625,2378933.155 4741356.7040625)',900913)')")
PostGIS认为您试图提交一个格式不正确的字符串,中间有未标注的单引号
切换您的查询字符串生成器来执行应该工作:
var query = client.query("INSERT INTO pins (p_geom) values("+pra+")")
但不要这样做
你现在面临SQL注入攻击,因为有人可能会破解HTTP请求,偷偷发送一些东西,而不是你期望的几何WKT。不要使用字符串串联将web浏览器的输入嵌入到数据库查询中,因为它绕过了框架的一些安全功能。
现在,回到您第一次尝试使用参数化查询:
node.js库正试图准备将参数插入数据库,并将其视为字符串,用单引号将其包围,并转义所有嵌入的单引号。这导致查询以以下形式发送到PostGIS:
INSERT INTO pins(p_geom) values('ST_GeomFromText(''LINESTRING(2335859.0225 4725430.1340625,2378933.155 4741356.7040625)'',900913)')
PostGIS随后尝试通过解析字符串将其转换为几何图形,并抱怨有效的几何图形不会以"ST"开头
不将ST_GeomFromText(...)
作为String参数传递,而只传递查询中真正是字符串的部分—WKT。类似这样的东西:
var wkt = "LINESTRING("+geo+")";
var query = client.query('INSERT INTO pins(p_geom) values(ST_GeomFromText(?,900913))', [wkt])