scripting a google docs form submission

2019-01-16 12:00发布

问题:

I'm trying to create a bookmarklet that parses a page and sends the results to a googledocs spreadsheet via a form that I've defined.

The relevent bit of the script is:

var form = document.createElement("form");

form.action = "http://spreadsheets.google.com/formResponse?formkey=Fd0SHgwQ3YwSFd5UHZpM1QxMlNOdlE6MA&ifq";
form.method = "POST";
form.id="ss-form";
form.innerHTML = ["<input id='entry_0' name = 'entry.0.single' value = '" + orderDate + "'/>", "<input name = 'entry.2.single' value = '" + email + "'/>", "<input name = 'entry.3.single' value = '" + customerID + "'/>", ].join("");
form.submit();


alert(form.innerHTML);

// returns:

Nothing is being saved to the form via the bookmarklet - any way to capture google's response in my bookmarklet's code? (fwiw, i've injected jQuery via jQueryify)

EDIT:

Firebug's Net panel isn't hearing any of the activity triggered by the bookmarklet - How about i approach this from goolgle's viewform method instead of formresponse.

The form i'm trying to submit is located at:

http://spreadsheets.google.com/viewform?hl=en&formkey=dFd0SHgwQ3YwSFd5UHZpM1QxMlNOdlE6MA

How can I go about injecting the script values into that form and then submitting that - again...via script within the bookmarklet that would have been triggered while on the page being parsed?

回答1:

if your already using jquery, try submitting the form via ajax ($.ajax). You can setup a success function that will be called when google sends back their response.

alternatively you should be able to use firebug to view the response google sends back.

Specifically I was thinking you could try something like the following:

$.ajax({
  url: "http://spreadsheets.google.com/formResponse",
  data: { formkey: "Fd0SHgwQ3YwSFd5UHZpM1QxMlNOdlE6MA&ifq", "entry.0.single": orderDate, "entry.2.single": email, "entry.3.single": customerID },
  type: "POST",
  dataType: "xml",
  success: function(data, textStatus, XMLHttpRequest) {
    console.log("success");
    console.log(data);
  },
  error: function(XMLHttpRequest, textStatus, errorThrown) {
    console.log("error");
    console.log(textStatus);
  },
})


回答2:

I've just made such a thing. Here's a break down of my process.

I need to keep a list of quotes from different web pages, and to add some info to each quote.

My bookmarklet will dynamically generate a google form (I've just viewed the source of the real google form that I've already created), it'll automatically fill the current url, the page title, and the currently selected text, than, the form will be submitted.

Since I need to manually add info, I intentionally didn't include at least one required field, so I receive the google form with an error message (but with url, title & quote already filled). Now I can manually add all the other info that I need and submit the form.

If the bookmarklet fill all the required fields you'll just receive the google form success response "Thanks! Your response has been recorded."

I've used the following site to generate a bookmarklet that use jQuery: http://benalman.com/code/test/jquery-run-code-bookmarklet/ (I'm using jQuery to be able to scrap additional info & content from the webpage)

To be able to use that site properly, you'll have to escape your one-liner html (you can use this escape tool)

The required steps are:

  1. Create a google form / spreadsheets
  2. View the source of the form and copy the fields you want the bookmarklet to fill
  3. Escape your html and use this to write your script that fill the info, this site will create the bookmarklet for you

So in my case:

1. I've created a form that include one text field to hold the url, another text field to hold the title of the page, a paragraph text to hold the quote (the selected text). The form also include some other required fields that I fill manually.

2. I prepared the following html:

    <form method="POST"
        action="https://spreadsheets.google.com/spreadsheet/formResponse?formkey=XYZXYZXYZXYZXYZXYZXYZ&amp;ifq">
    <input type="text" name="entry.0.single" value="" id="entry_0" />
    <input type="text" name="entry.3.single" value="" id="entry_3" />
    <textarea name="entry.2.single" id="entry_2"></textarea>
    <input type="submit" name="submit" value="submit" />
    </form>

(entry_0 - url, entry_3 - page title, entry_2 - quote)

3. After putting it in one line and escaping it. I've used the following script:

frm = $(unescape('%3Cform%20action%3D%22https%3A//spreadsheets.google.com/spreadsheet/formResponse%3Fformkey%3DXYZXYZXYZXYZXYZXYZXYZ%26amp%3Bifq%22%20method%3D%22POST%22%3E%0A%3Cinput%20type%3D%22text%22%20name%3D%22entry.0.single%22%20value%3D%22%22%20id%3D%22entry_0%22%20/%3E%0A%3Cinput%20type%3D%22text%22%20name%3D%22entry.3.single%22%20value%3D%22%22%20id%3D%22entry_3%22%20/%3E%0A%3Ctextarea%20name%3D%22entry.2.single%22%20id%3D%22entry_2%22%3E%3C/textarea%3E%0A%3Cinput%20type%3D%22submit%22%20name%3D%22submit%22%20value%3D%22submit%22%20/%3E%0A%3C/form%3E'));
$(frm).children('#entry_0').attr('value',location.href);
$(frm).children('#entry_3').attr('value',$('title')[0].innerHTML);
$(frm).children('#entry_2').html(window.getSelection().toString());
$(frm).children('input[type=submit]').click()

This method has been tested with chrome. Good luck!



回答3:

For anyone in the future, make sure the URL you're posting to has &ifq at the end, I've found that this has easily fixed most of my issues with 405 returns.



回答4:

As of today I could not get the answer marked right to work. I believe google has changed a few things.

I could get it to work by doing a HTTP POST to https://docs.google.com/forms/d/<form_id>/formResponse

with form data as entry.645136839=<somevalue> where the big number is obtained from the form field.



回答5:

I don't have a complete answer, but I have been able to make it work using Curl:

curl http://spreadsheets.google.com/formResponse?formkey=dFpVLTVFY2t5dWdoNTZpNERwWDRxX2c6MQ&ifq --data entry.0.single=eric --data entry.1.single=pugh

Also, I am able to have it work via Ajax using prototype, but ONLY on Safari.

I too get the same 405 Method not allowed in Firefox. Here is my script:

function vote_for_synonym(word1, word2){
word1 = encodeURIComponent(word1);
word2 = encodeURIComponent(word2);

$req = new Ajax.Request("http://spreadsheets.google.com/formResponse?formkey=dFpVLTVFY2t5dWdoNTZpNERwWDRxX2c6MQ", {
  method: 'post',
  contentType: 'application/x-www-form-urlencoded',
  onCreate: function(){
   Element.show('systemWorking');
  },
  onSuccess: function() {
    Element.show('thanks');
    Element.hide('systemWorking')
  },
  onFailure: function() {
    Element.show('error');
  }
});           

}

Also, my onFailure never gets called, just onSuccess.



回答6:

I thought I had a few tidbits to add to this, but they turn out to NOT solve the problem.

  • definitely use the input 'name' (not id)
  • one of the other parameters is 'ifq', not sure how it works to bundle this with 'formkey' (a string is just a string, right?)
  • to completely mock the Google form, add these additional fields: pageNumber=0; backupCache=''; submit=Submit

I get the same '405 Method not allowed' error though...



回答7:

From your sample code - I've changed a couple of things - firstly the form submission end point / no &ifq needed. Google has probably updated things. View the source of your form and use the form action URL. secondly & critically your form input types didn't include the ids (except for the first one). With these things - the form posted successfully.

<html>
<body>
<script type="text/javascript">
var form = document.createElement("form");

form.action = "https://docs.google.com/a/yourdomain.com/forms/d/XXXXXXXXXXXXXXXXXXXX/formResponse";
form.method = "POST";
form.id="ss-form";
var repo = "https://github.com/fredericcormier/WesternMusicElements";
var branch = "master";
var email = "";

form.innerHTML = ["<input id='entry_639106242' name = 'entry.639106242' value = '" + repo + "'/>","<input id='entry_1546762025' name = 'entry.1546762025' value = '" + branch + "'/>","<input id='entry_1509161732' name = 'entry.1509161732' value = '" + email + "'/>", ].join("");
form.submit();

alert(form.innerHTML);

</script>

</body>
</html>