javascript function to encode everything?

R

Richard Trahan

I need a javascript function to hex-encode a plus sign so I can
pass the plus sign as an argument in a GET request. escape() and
encodeURI() don't do it (and probably shouldn't, because '+' is
a valid character in a URI). I could write a regexp, but the
environment I'm in won't allow replace(). I could write something
cumbersome using indexOf, but if there's something easier, like
a builtin function that encodes every character in the string, I'd
prefer that. I'm a newbie at js, so type slowly, please.
 
T

Thomas 'PointedEars' Lahn

Richard said:
I need a javascript function to hex-encode a plus sign so I can
pass the plus sign as an argument in a GET request. escape() and
encodeURI() don't do it (and probably shouldn't, because '+' is
a valid character in a URI). I could write a regexp, but the
environment I'm in won't allow replace(). I could write something
cumbersome using indexOf, but if there's something easier, like
a builtin function that encodes every character in the string, I'd
prefer that.

There is not.
I'm a newbie at js, so type slowly, please.

How many characters per minute are allowed in this newsgroup?
I cna tpye 500 wrods pre mnitue!!1 ;-)

Seriously, I'm afraid there is no easy solution, especially because the
available methods of your implementation are virtually unknown. Maybe
you are looking for this:

/**
* @author
* (C) 2001-2004 Thomas Lahn <[email protected]>
* Distributed under the GNU GPL v2.
* @partof
* http://pointedears.de/scripts/string.js
* @argument _ sText
* @argument string sReplaced
* @argument string sReplacement
* @return type string
*/
function replaceText(sText, sReplaced, sReplacement)
{
var result = "";
var t;
if (!sText && sText.constructor == String)
{
sText = this;
}

var sNewText = sText;
var a;
// alert(sText);
if (sText && sReplaced && sReplacement)
{
if (sText.replace)
{
sReplaced = sReplaced.replace(/\\/g, "\\\\");
/* Version 1.23.2002.4 bugfix: allows to replace \ with other
* strings, required for proper rxReplaced;
* Example (no quotes, no escaping):
* sReplaced (provided) "\\"
* sReplaced (evaluated) \
* sReplaced (replaced as formulated above) "\\\\"
* sReplaced (esc. in RegExp constructor) "\\\\"
* sReplaced (ev. in RegExp constructor) \\
* rxReplaced (with RegExp escaping) /\\/g
* rxReplaced (evaluated) all occurr. of \
*/
var rxReplaced = new RegExp(sReplaced, "g");
sText = sText.replace(rxReplaced, sReplacement);

result = sText;
}
else if (sText.split
&& (sReplaced = sReplaced.replace(/\\/g, "\\\\"))
&& (a = sText.split(sReplaced))
&& a.join)
{
result = a.join(sReplacement);
}
else
{
var i = sText.indexOf(sReplaced);

if (i > -1)
{
sNewText = sText.substring(0, i);
sNewText += sReplacement
+ replaceText(
sText.substring(i + sReplaced.length),
sReplaced,
sReplacement);
}

result = sNewText;
}
}

return result;
}

var f = this.encodeURI || this.escape || function dummy(s) { return s; };
var plusEscape = "%" + "+".charCodeAt(0).toString(16).toUpperCase();
var x = replaceText(f("foo"), "+", plusEscape);

This will use the return value of encodeURI() or escape(), if available,
to escape the usual characters (why reinvent the wheel?) which is passed
to replaceText() which uses two alternatives if String.prototype.replace()
is unavailable:

A) sText.split(sReplaced).join(sReplacement)
B) calling the method recursively until every occurrence was replaced

You wrote that String.prototype.replace() is not available. This method was
introduced in JavaScript 1.2, so your implementation may be of the level of
JavaScript 1.1. String.prototype.split() and Array.prototype.join() are
available there, so it is likely that your implementation will use
alternative A.


HTH

PointedEars
 
T

Thomas 'PointedEars' Lahn

[Previous posting canceled because of flaws in the implementation]

Richard said:
I need a javascript function to hex-encode a plus sign so I can
pass the plus sign as an argument in a GET request. escape() and
encodeURI() don't do it (and probably shouldn't, because '+' is
a valid character in a URI). I could write a regexp, but the
environment I'm in won't allow replace(). I could write something
cumbersome using indexOf, but if there's something easier, like
a builtin function that encodes every character in the string, I'd
prefer that.

There is not.
I'm a newbie at js, so type slowly, please.

How many characters per minute are allowed in this newsgroup?
I cna tpye 500 wrods pre mnitue!!1 ;-)

Seriously, I'm afraid there is no easy solution, especially because the
available methods of your implementation are virtually unknown. Maybe
you are looking for this:

var f = this.encodeURI || this.escape || function dummy(s) { return s; };
var plusEscape = "%" + "+".charCodeAt(0).toString(16).toUpperCase();
var x = f("foo").split("+").join(plusEscape);

This will use the return value of encodeURI() or escape(), if available,
to escape the usual characters in "foo" (why reinvent the wheel?). Then
the "+" character is replaced with its escape sequence.

You wrote that String.prototype.replace() is not available. This method
was introduced in JavaScript 1.2, so your implementation may be of the
level of JavaScript 1.1. String.prototype.split() and
Array.prototype.join() are available there, so it is likely that this will
work.


HTH

PointedEars
 
T

Thomas 'PointedEars' Lahn

Thomas said:
Richard said:
I need a javascript function to hex-encode a plus sign so I can
pass the plus sign as an argument in a GET request. escape() and
encodeURI() don't do it (and probably shouldn't, because '+' is
a valid character in a URI). [...]

[...]
You wrote that String.prototype.replace() is not available. This method
was introduced in JavaScript 1.2, so your implementation may be of the
level of JavaScript 1.1.

Which makes me wonder why it understands then encodeURI()
as of ECMAScript 3. Are you sure about replace()?


PointedEars
 
R

Richard Trahan

Thomas said:
Which makes me wonder why it understands then encodeURI()
as of ECMAScript 3. Are you sure about replace()?
I thank you profusely for your assistance, so I guess I
owe you an explanation about the replace(). It's not a
matter of js version. It's going to execute within an
eBay ad. eBay software will not allow js in an ad that
can modify text in such a way that simple software can't
scan the new text for forbidden phrases.
That means no replace() and no <script> tags
with a src attribute, which is why the method in your
first post won't work, but the method in your second
post will probably be ok. Anyway, I'm using a workaround
until I understand js a bit more; instead of using ?x=y
syntax and CGI to unpack the lone argument,
I'm using ?arg syntax and using ENV{QUERY_STRING} in the
Perl script that reads the GET, in which case any
character at all can be passed (it's the CGI::param method
that throws away the plus sign).

I'm determined to defeat eBay's restriction. They have a
nasty habit of changing ad requirements almost weekly, which
causes scores of people to manually edit thousands of ads
because the ad content cannot be served remotely. One possibility
is to reduce everything to images, but the file sizes would
be too large for folks with dialups. Another possibility is
to encode text characters disguised as image bytes (steganography),
but I don't know if js can unpack an image into its bytes.
Do you know?
 
M

Michael Winter

[snip]
Another possibility is to encode text characters disguised as imagebytes
(steganography), but I don't know if js can unpack an imageinto its
bytes.
Do you know?

No, it can't.

Back to the original encoding question...

Whilst encodeURI() won't escape a plus (+) symbol, encodeURIComponent()
will. As you acknowledge, a plus symbol is valid within a URI, globally,
but the components (scheme, host, path, etc.) do not allow them.

Of course, this is of little use with older browsers, but I thought it
worth mentioning.

Mike
 
T

Thomas 'PointedEars' Lahn

Richard said:
I thank you profusely for your assistance,

I thank *you*. I seldom get such kind responses.
so I guess I owe you an explanation about the replace(). It's not a matter
of js version. It's going to execute within an eBay ad. eBay software will
not allow js in an ad that can modify text in such a way that simple
software can't scan the new text for forbidden phrases.
ACK

That means no replace() and no <script> tags with a src attribute, which
is why the method in your first post won't work,

It was flawed anyway which is why I finally canceled the posting.
but the method in your second post will probably be ok.
Hopefully.

Anyway, I'm using a workaround until I understand js a bit more; instead
of using ?x=y syntax and CGI to unpack the lone argument, I'm using ?arg
syntax and using ENV{QUERY_STRING} in the Perl script that reads the GET,
in which case any character at all can be passed (it's the CGI::param
method that throws away the plus sign).

If you have the choice, you should always prefer the server-side approach
(which can be server-side JS, too) above the client-side one since
client-side scripting can be restricted or disabled by the the user or not
even present, while you often have full control over your server-side app.
Client-side scripting comes in handy when roundtrips/traffic should be
reduced; it is nothing that should be relied upon on a Web site.
I'm determined to defeat eBay's restriction. They have a
nasty habit of changing ad requirements almost weekly, which
causes scores of people to manually edit thousands of ads
because the ad content cannot be served remotely. One possibility
is to reduce everything to images, but the file sizes would
be too large for folks with dialups.

Yes, please do not do that. I remember the Web was not as much fun when I
only had 56k dial-up a few months before because many sites were optimized
(I'd say pessimized[tm]) for broadband use. I effectively had to disable
all images (or have much time) for reasonable usage.
Another possibility is to encode text characters disguised as image bytes
(steganography), but I don't know if js can unpack an image into its
bytes. Do you know?

I'm afraid JS itself cannot, it needs a host object to do so. As the host
environment to provide such an object is the Web browser and there is more
than one of them, there is no way this can be reliably implemented on an
*Internet* Web site.


PointedEars
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,780
Messages
2,569,611
Members
45,280
Latest member
BGBBrock56

Latest Threads

Top