เพียงแค่สงสัยว่ามีอะไรในตัว Javascript ที่สามารถใช้แบบฟอร์มและส่งคืนพารามิเตอร์การค้นหาเช่น: "var1=value&var2=value2&arr[]=foo&arr[]=bar..."
ฉันสงสัยมานานหลายปีแล้ว
เพียงแค่สงสัยว่ามีอะไรในตัว Javascript ที่สามารถใช้แบบฟอร์มและส่งคืนพารามิเตอร์การค้นหาเช่น: "var1=value&var2=value2&arr[]=foo&arr[]=bar..."
ฉันสงสัยมานานหลายปีแล้ว
คำตอบ:
ฉันพยายามค้นหาคำตอบของคำถามนี้เมื่อไม่นานมานี้ แต่ฉันได้เขียนฟังก์ชั่นของตัวเองที่ดึงค่าออกมาจากแบบฟอร์ม ..
มันไม่สมบูรณ์แบบ แต่เหมาะกับความต้องการของฉัน
function form_params( form )
{
var params = new Array()
var length = form.elements.length
for( var i = 0; i < length; i++ )
{
element = form.elements[i]
if(element.tagName == 'TEXTAREA' )
{
params[element.name] = element.value
}
else if( element.tagName == 'INPUT' )
{
if( element.type == 'text' || element.type == 'hidden' || element.type == 'password')
{
params[element.name] = element.value
}
else if( element.type == 'radio' && element.checked )
{
if( !element.value )
params[element.name] = "on"
else
params[element.name] = element.value
}
else if( element.type == 'checkbox' && element.checked )
{
if( !element.value )
params[element.name] = "on"
else
params[element.name] = element.value
}
}
}
return params;
}
form_params ส่งคืนการแม็พ (คีย์ -> ค่า) ของพารามิเตอร์ อินพุตเป็นองค์ประกอบแบบฟอร์ม (องค์ประกอบ DOM)
มันไม่ได้จัดการเขตข้อมูลที่อนุญาตให้เลือกหลายรายการ
new Array()
เพื่อเริ่มต้นพจนานุกรม แต่อีกครั้งรหัสดูสะอาดกว่าอึฉันจะเขียนวันนี้!
อัปเดต 2k20: ใช้ของ Joshวิธีการแก้ปัญหาที่มีURLSearchParams.toString ()
คำตอบเก่า:
ไม่มี jQuery
var params = {
parameter1: 'value_1',
parameter2: 'value 2',
parameter3: 'value&3'
};
var esc = encodeURIComponent;
var query = Object.keys(params)
.map(k => esc(k) + '=' + esc(params[k]))
.join('&');
สำหรับเบราว์เซอร์ที่ไม่รองรับไวยากรณ์ฟังก์ชันลูกศรซึ่งต้องใช้ ES5 ให้เปลี่ยน.map...
บรรทัดเป็น
.map(function(k) {return esc(k) + '=' + esc(params[k]);})
หากคุณใช้ jQuery คุณอาจต้องการดูjQuery.param()
http://api.jquery.com/jQuery.param/
ตัวอย่าง:
var params = {
parameter1: 'value1',
parameter2: 'value2',
parameter3: 'value3'
};
var query = $.param(params);
document.write(query);
$.param($('#myform').serializeArray())
สตริงแบบสอบถามสำหรับรูปแบบคือ
$('#myform').serialize()
jQuery !== JavaScript
jQuery.param()
ที่นี่github.com/jquery/jquery/blob/master/src/serialize.js :)
someStr=value1&someObj[a]=5&someObj[b]=6&someArr[]=1&someArr[]=2
URLSearchParams APIมีอยู่ในเบราว์เซอร์ที่ทันสมัยทั้งหมด ตัวอย่างเช่น:
const params = new URLSearchParams({
var1: "value",
var2: "value2",
arr: "foo",
});
console.log(params.toString());
//Prints "var1=value&var2=value2&arr=foo"
params.append(key, value)
ภายหลังเพื่อเพิ่ม params การค้นหาใหม่ในสถานการณ์ที่ซับซ้อนมากขึ้น
x=null&y=undefined
const url = new URL("https://stackoverflow.com")
) คุณสามารถตั้งค่าสตริงการสืบค้นurl.search = new URLSearchParams({foo: "bar"})
หรือurl.searchParams.append("foo", "bar")
สิ่งนี้ไม่ได้ตอบคำถามของคุณโดยตรง แต่นี่เป็นฟังก์ชันทั่วไปที่จะสร้าง URL ที่มีพารามิเตอร์สตริงข้อความค้นหา พารามิเตอร์ (ชื่อและค่า) ปลอดภัยสำหรับการรวมไว้ใน URL อย่างปลอดภัย
function buildUrl(url, parameters){
var qs = "";
for(var key in parameters) {
var value = parameters[key];
qs += encodeURIComponent(key) + "=" + encodeURIComponent(value) + "&";
}
if (qs.length > 0){
qs = qs.substring(0, qs.length-1); //chop off last "&"
url = url + "?" + qs;
}
return url;
}
// example:
var url = "http://example.com/";
var parameters = {
name: "George Washington",
dob: "17320222"
};
console.log(buildUrl(url, parameters));
// => http://www.example.com/?name=George%20Washington&dob=17320222
new Array
ในขณะที่คุณใช้มันเป็นวัตถุจริงๆ o, O
ด้วย jQuery คุณสามารถทำได้โดย $.param
$.param({ action: 'ship', order_id: 123, fees: ['f1', 'f2'], 'label': 'a demo' })
// -> "action=ship&order_id=123&fees%5B%5D=f1&fees%5B%5D=f2&label=a+demo"
การใช้งานObject.entries()
ซึ่งส่งกลับอาร์เรย์ของ[key, value]
คู่ของวัตถุ ตัวอย่างเช่นสำหรับมันจะกลับมา{a: 1, b: 2}
[['a', 1], ['b', 2]]
ไม่รองรับ (และจะไม่) โดย IE เท่านั้น
const buildURLQuery = obj =>
Object.entries(obj)
.map(pair => pair.map(encodeURIComponent).join('='))
.join('&');
buildURLQuery({name: 'John', gender: 'male'});
"name=John&gender=male"
ไม่ฉันไม่คิดว่ามาตรฐาน JavaScript ได้ว่าในตัว แต่ต้นแบบ JS มีฟังก์ชั่น (JS แน่นอนกรอบอื่น ๆ ส่วนใหญ่จะมีมากเกินไป แต่ผมไม่ทราบว่าพวกเขา) พวกเขาเรียกว่าเป็นอันดับ
ฉันขอแนะนำ Prototype JS มันใช้งานได้ดี ข้อเสียเปรียบเพียงอย่างเดียวที่ฉันสังเกตเห็นมันคือขนาด (ไม่กี่ร้อย kb) และขอบเขต (มีโค้ดจำนวนมากสำหรับ ajax, dom และอื่น ๆ ) ดังนั้นถ้าคุณต้องการ serializer แบบฟอร์มมัน overkill และพูดอย่างเคร่งครัดถ้าคุณต้องการมันเป็นฟังก์ชัน Ajax (ซึ่งส่วนใหญ่คือสิ่งที่ฉันใช้เพื่อ) มันเป็น overkill นอกจากว่าคุณระวังตัวคุณอาจพบว่ามันเป็น "เวทมนต์" มากเกินไป (เช่นการขยายองค์ประกอบ dom ทุกชิ้นที่สัมผัสกับฟังก์ชั่น Prototype JS เพื่อค้นหาองค์ประกอบ) ทำให้ช้าลงในกรณีที่รุนแรง
การสอบถามสามารถช่วยได้
คุณสามารถ
const querystring = require('querystring')
url += '?' + querystring.stringify(parameters)
หากคุณไม่ต้องการใช้ห้องสมุดสิ่งนี้ควรครอบคลุมประเภทองค์ประกอบแบบฟอร์มส่วนใหญ่ / ทั้งหมดเดียวกัน
function serialize(form) {
if (!form || !form.elements) return;
var serial = [], i, j, first;
var add = function (name, value) {
serial.push(encodeURIComponent(name) + '=' + encodeURIComponent(value));
}
var elems = form.elements;
for (i = 0; i < elems.length; i += 1, first = false) {
if (elems[i].name.length > 0) { /* don't include unnamed elements */
switch (elems[i].type) {
case 'select-one': first = true;
case 'select-multiple':
for (j = 0; j < elems[i].options.length; j += 1)
if (elems[i].options[j].selected) {
add(elems[i].name, elems[i].options[j].value);
if (first) break; /* stop searching for select-one */
}
break;
case 'checkbox':
case 'radio': if (!elems[i].checked) break; /* else continue */
default: add(elems[i].name, elems[i].value); break;
}
}
}
return serial.join('&');
}
คุณไม่จำเป็นต้องใช้แบบฟอร์มในการทำสิ่งนี้กับ Prototype เพียงใช้ฟังก์ชัน Object.toQueryString :
Object.toQueryString({ action: 'ship', order_id: 123, fees: ['f1', 'f2'], 'label': 'a demo' })
// -> 'action=ship&order_id=123&fees=f1&fees=f2&label=a%20demo'
คุณสามารถทำเช่นนั้นในปัจจุบันด้วยFormData
และURLSearchParams
ไม่ต้องห่วงอะไร
const formData = new FormData(form);
const searchParams = new URLSearchParams(formData);
const queryString = searchParams.toString();
เบราว์เซอร์ที่เก่ากว่าจะต้องใช้ polyfill
ฉันไม่แน่ใจตัวเองทั้งหมดฉันจำได้ว่าเห็น jQuery ทำมันถึงขนาด แต่มันไม่ได้จัดการระเบียนลำดับชั้นเลยให้อยู่คนเดียวในวิธีที่เป็นมิตรกับ PHP
สิ่งหนึ่งที่ฉันรู้แน่ ๆ ก็คือเมื่อสร้าง URL และติดผลิตภัณฑ์ลงใน dom ไม่เพียง แต่ใช้ string-glue ทำมันหรือคุณจะเปิดตัวเองไปที่ตัวแบ่งหน้าเว็บที่มีประโยชน์
ตัวอย่างเช่นซอฟต์แวร์โฆษณาบางรายการจะจัดเรียงสตริงเวอร์ชันจากสิ่งที่เรียกใช้แฟลชของคุณ นี่เป็นเรื่องปกติเมื่อสตริงธรรมดาทั่วไปของ adobes แต่มันไร้เดียงสามากและทำให้เกิดความอับอายสำหรับผู้ที่ติดตั้ง Gnash เนื่องจากสตริงของ gnash'es นั้นมีลิขสิทธิ์ GPL ที่เต็มไปด้วย URL ที่สมบูรณ์ และ <a href> แท็ก การใช้สิ่งนี้ในเครื่องมือสร้างสตริงโฆษณาติดกาวของคุณจะส่งผลให้มีการเปิดหน้าเว็บและมี HTML ที่ไม่สมดุลปรากฏขึ้นใน dom
คุณธรรมของเรื่องราว:
var foo = document.createElement("elementnamehere");
foo.attribute = allUserSpecifiedDataConsideredDangerousHere;
somenode.appendChild(foo);
ไม่:
document.write("<elementnamehere attribute=\""
+ ilovebrokenwebsites
+ "\">"
+ stringdata
+ "</elementnamehere>");
Google จำเป็นต้องเรียนรู้เคล็ดลับนี้ ฉันพยายามที่จะรายงานปัญหาพวกเขาดูเหมือนจะไม่สนใจ
สำหรับพวกเราที่ชอบ jQuery คุณจะต้องใช้ form plugin: http://plugins.jquery.com/project/formซึ่งมีเมธอด formSerialize
อาจจะซ้ำซ้อนเล็กน้อย แต่วิธีที่สะอาดที่สุดที่ฉันพบซึ่งสร้างจากคำตอบบางส่วนที่นี่:
const params: {
key1: 'value1',
key2: 'value2',
key3: 'value3',
}
const esc = encodeURIComponent;
const query = Object.keys(params)
.map(k => esc(k) + '=' + esc(params[k]))
.join('&');
return fetch('my-url', {
method: 'POST',
headers: {'Content-Type': 'application/x-www-form-urlencoded'},
body: query,
})
คำตอบเหล่านี้มีประโยชน์มาก แต่ฉันต้องการเพิ่มอีกคำตอบที่อาจช่วยให้คุณสร้าง URL แบบเต็ม นี้สามารถช่วยคุณฐาน concat url
, path
, และhash
parameters
var url = buildUrl('http://mywebsite.com', {
path: 'about',
hash: 'contact',
queryParams: {
'var1': 'value',
'var2': 'value2',
'arr[]' : 'foo'
}
});
console.log(url);
คุณสามารถดาวน์โหลดผ่านทาง npm https://www.npmjs.com/package/build-url
การสาธิต:
;(function () {
'use strict';
var root = this;
var previousBuildUrl = root.buildUrl;
var buildUrl = function (url, options) {
var queryString = [];
var key;
var builtUrl;
var caseChange;
// 'lowerCase' parameter default = false,
if (options && options.lowerCase) {
caseChange = !!options.lowerCase;
} else {
caseChange = false;
}
if (url === null) {
builtUrl = '';
} else if (typeof(url) === 'object') {
builtUrl = '';
options = url;
} else {
builtUrl = url;
}
if(builtUrl && builtUrl[builtUrl.length - 1] === '/') {
builtUrl = builtUrl.slice(0, -1);
}
if (options) {
if (options.path) {
var localVar = String(options.path).trim();
if (caseChange) {
localVar = localVar.toLowerCase();
}
if (localVar.indexOf('/') === 0) {
builtUrl += localVar;
} else {
builtUrl += '/' + localVar;
}
}
if (options.queryParams) {
for (key in options.queryParams) {
if (options.queryParams.hasOwnProperty(key) && options.queryParams[key] !== void 0) {
var encodedParam;
if (options.disableCSV && Array.isArray(options.queryParams[key]) && options.queryParams[key].length) {
for(var i = 0; i < options.queryParams[key].length; i++) {
encodedParam = encodeURIComponent(String(options.queryParams[key][i]).trim());
queryString.push(key + '=' + encodedParam);
}
} else {
if (caseChange) {
encodedParam = encodeURIComponent(String(options.queryParams[key]).trim().toLowerCase());
}
else {
encodedParam = encodeURIComponent(String(options.queryParams[key]).trim());
}
queryString.push(key + '=' + encodedParam);
}
}
}
builtUrl += '?' + queryString.join('&');
}
if (options.hash) {
if(caseChange)
builtUrl += '#' + String(options.hash).trim().toLowerCase();
else
builtUrl += '#' + String(options.hash).trim();
}
}
return builtUrl;
};
buildUrl.noConflict = function () {
root.buildUrl = previousBuildUrl;
return buildUrl;
};
if (typeof(exports) !== 'undefined') {
if (typeof(module) !== 'undefined' && module.exports) {
exports = module.exports = buildUrl;
}
exports.buildUrl = buildUrl;
} else {
root.buildUrl = buildUrl;
}
}).call(this);
var url = buildUrl('http://mywebsite.com', {
path: 'about',
hash: 'contact',
queryParams: {
'var1': 'value',
'var2': 'value2',
'arr[]' : 'foo'
}
});
console.log(url);
ฉันรู้ว่านี่เป็นคำตอบที่ล่าช้ามาก แต่ทำงานได้ดีมาก ...
var obj = {
a:"a",
b:"b"
}
Object.entries(obj).map(([key, val])=>`${key}=${val}`).join("&");
หมายเหตุ: object.entries จะส่งคืนคีย์คู่ค่า
เอาต์พุตจากบรรทัดด้านบนจะเป็นa = a & b = b
หวังว่ามันช่วยใครบางคน
การเข้ารหัสที่มีความสุข ...
อาจจะสายเกินไปที่จะตอบคำถามของคุณ
ฉันมีคำถามเดียวกันและไม่ต้องการต่อท้ายสตริงเพื่อสร้าง URL ดังนั้นฉันเริ่มใช้ $ .param ตามที่Techhouseอธิบาย
ฉันยังพบห้องสมุดURI.jsที่สร้าง URL ให้คุณได้อย่างง่ายดาย มีหลายตัวอย่างที่จะช่วยให้คุณเป็น: URI.js เอกสาร
นี่คือหนึ่งในนั้น:
var uri = new URI("?hello=world");
uri.setSearch("hello", "mars"); // returns the URI instance for chaining
// uri == "?hello=mars"
uri.setSearch({ foo: "bar", goodbye : ["world", "mars"] });
// uri == "?hello=mars&foo=bar&goodbye=world&goodbye=mars"
uri.setSearch("goodbye", "sun");
// uri == "?hello=mars&foo=bar&goodbye=sun"
// CAUTION: beware of arrays, the following are not quite the same
// If you're dealing with PHP, you probably want the latter…
uri.setSearch("foo", ["bar", "baz"]);
uri.setSearch("foo[]", ["bar", "baz"]);`
var params = { width:1680, height:1050 };
var str = jQuery.param( params );
console.log(str)
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>