I have a PHP file on a URL that processes data sent from an API. I can't access the sending server to redirect, duplicate or test that feed to a staging server.
What code can I put in the processing file that will send a duplicate of the POST variables to another URL?
Is it a question of processing all POST variables into a new form and then submitting the form after the live code has run?
<form id='forwarding-form' action="https://stagingURL" method = "post">
<? foreach ($_POST as $key=>$value) {
echo "<input type = 'hidden' name='$key' value='$value'>";
} ?>
</form>
then at the end of the file
<script>
$('#forwarding-form').submit();
</script>
Will this work?
Or is there a more direct or elegant way?
Related
I am using a Google Script to generate tickets to an event, and the ticket includes a QR code which goes to a pre-filled Google Form link. Since it's pre-filled, the string is quite long, and the Google Charts API for creating QR codes will not accept a string of text that long using a GET request, but I can't find any documentation of how to code the POST request into Apps Script. How do I generate a POST request in Apps Script that will return an image of the QR code which I can then insert into the document?
I already tried the GET request, and it truncates the URL before encoding it into a QR code. That gets me to the Google Form, but not the pre-filled version that the link generates (actually pretty smart on Google's part to have it truncate the string in a place that still gives a usable URL, but that's for another day...)
I have also tried the HtmlService to render the QR code using the POST method with the Charts API in an HTML form that automatically submits on the loading of that HTML. If I use showSidebar(), this will open the image in a new tab, but I haven't figured out how to return that image so that it can be inserted into the document.
I've also tried creating a blob with the HTML and then saving the blob as a PNG, but from the research I've done, the .getAs() method doesn't render images when converting the HTML.
The renderQR function:
function renderQR(inputUrl) {
var html = HtmlService.createTemplateFromFile('QREncode.html');
html.url = inputUrl;
var rendered = html.evaluate().setSandboxMode(HtmlService.SandboxMode.IFRAME)
.setHeight(300)
.setWidth(300);
return rendered;
}
The QREncode.html file:
<!DOCTYPE html>
<html>
<head>
<base target="_top">
<script type='application/javascript'>
// Send the POST when the page is loaded,
// which will replace this whole page with the retrieved chart.
function loadGraph() {
var frm = document.getElementById('post_form');
if (frm) {
frm.submit();
}
}
</script>
</head>
<body onload="loadGraph()">
<form action='https://chart.googleapis.com/chart' method='POST' id='post_form'>
<input type='hidden' name='cht' value='qr' />
<input type='hidden' name='chl' value='<?= url ?>' />
<input type='hidden' name='chs' value='300x300' />
<input type='submit'/>
</form>
</body>
</html>
When I treat the return from the renderQR() function as an image, Apps script gives an error saying that it is "Invalid image data", which makes sense -- but how do I convert it into an image, or is there a better or simpler way I could be doing this?
You need to get the qr code in the Apps Script, not in the browser:
var imageData = UrlFetchApp.fetch('https://chart.googleapis.com/chart', {
'method' : 'post',
'payload' : {
'cht': 'qr',
'chl': 'https://google.com',
'chs': '300x300'
}}).getContent();
For those looking for a formula solution (without Apps Script)
Reference: https://www.benlcollins.com/spreadsheets/qr-codes-in-google-sheets/
Solution:
=IMAGE("https://chart.googleapis.com/chart?chs=250x250&cht=qr&chl="&ENCODEURL(A1))
I am making a very simple web app using the rust Rocket framework. I have a very simple HTML file that has a form, as follows:
<form action="/search" method="post" accept-charset="utf-8">
Search Term:<input type="text" name="searchterm">
<input type="submit" value="search">
</form>
Next, here are my rocket functions to deal with the requests. I have a get function that spits out index.html when accessing "/", then for my form, I have the following functions:
#[derive(FromForm)]
pub struct Request<'r> {
payload: &'r RawStr,
// we can add more if we want later on, for other form options...
}
#[post("/search", data = "<data>")]
pub fn process(data: Form<Request>) -> Result<Redirect, String> {
if data.payload == "Hello!" {
Ok(Redirect::to("/search/Hello"))
} else {
Err(format!("Unknown search term, '{}'.", data.payload))
}
}
Then, this is to response to the GET requests:
#[get("/search/<term>")]
pub fn response(term: &RawStr) -> String {
format!("You typed in {}.", term)
}
Like I said, very simple, very barebones, just trying to tiptoe into both Rust and Web Apps at the same time. I do not have much experience in either. My issue is, when using the field presented to the user in my html file, the server returns an error:
POST /search application/x-www-form-urlencoded:
=> Matched: POST /search (process)
=> Error: The incoming form failed to parse.
=> Outcome: Failure
=> Warning: Responding with 422 Unprocessable Entity catcher.
=> Response succeeded.
If I go directly, to localhost:8000/search/Hello! I can see that my GET response works. But if I use my form it refuses to parse. What am I doing wrong? I am simply attempting to make a web app that takes an input, and based on that input, returns something. Website redirection, web scraping, I am not sure on the specifics of functionality yet, but I need to be able to type something into the form and obtain it for use in my rust code later. Any help would be appreciated!
I think the problem is that your form parameter name (<input type="text" name="searchterm">) doesn't match with your struct field name (payload). If you rename one or the other so they would match, your form should work.
I'm new to Angular. I've tried everything I know how and Google searches have surprisingly few tutorials on this particular question. Here's the last code I tried:
index.html
<form ng-submit="addArticle(articles)">
<input type="text" id="title" ng-model="newPost.title">
<input type="text" id="body" ng-model="newPost.body">
<input type="submit" value="Submit">
</form>
articles controller
app.controller('ArticlesCtrl', function($scope, Article) {
$scope.articles = Article.query();
$scope.newPost = Article.save();
});
articles service (rails backend)
app.factory('Article', function($resource) {
return $resource('http://localhost:3000/articles');
});
I can retrieve data just fine. But I can't submit any new data to the rails backend. On page load, the rails server error is:
Started POST "/articles" for 127.0.0.1 at 2015-02-08 18:26:29 -0800
Processing by ArticlesController#create as HTML
Completed 400 Bad Request in 0ms
ActionController::ParameterMissing (param is missing or the value is empty: article):
app/controllers/articles_controller.rb:57:in `article_params'
app/controllers/articles_controller.rb:21:in `create'
Pressing the submit button does nothing at all. The form basically does not work and the page is looking for a submission as soon as it loads.
I understand what the error says, that it's not receiving the parameters from the form. What I don't understand is what that should look like in my controller and/or form.
What am I doing wrong and how do I fix this?
Angular has a feature called services which acts as a model for the application. It's where I'm communicating with my Rails backend:
services/article.js
app.factory('Article', function($resource) {
return $resource('http://localhost:3000/articles/:id', { id: '#id'},
{
'update': { method: 'PUT'}
});
});
Even though the :id is specified on the end, it works just as well for going straight to the /articles path. The id will only be used where provided.
The rest of the work goes into the controller:
controllers/articles.js
app.controller('NewPostCtrl', function($scope, Article) {
$scope.newPost = new Article();
$scope.save = function() {
Article.save({ article: $scope.article }, function() {
// Optional function. Clear html form, redirect or whatever.
});
};
});
Originally, I assumed that the save() function that's made available through $resources was somewhat automatic. It is, but I was using it wrong. The default save() function can take up to four parameters, but only appears to require the data being passed to the database. Here, it knows to send a POST request to my backend.
views/articles/index.html
<form name="form" ng-submit="save()">
<input type="text" id="title" ng-model="article.title">
<input type="text" id="body" ng-model="article.body">
<input type="submit" value="Submit">
</form>
After getting the service setup properly, the rest was easy. In the controller, it's required to create a new instance of the resource (in this case, a new article). I created a new $scope variable that contains the function which invokes the save method I created in the service.
Keep in mind that the methods created in the service can be named whatever you want. The importance of them is the type of HTTP request being sent. This is especially true for any RESTful app, as the route for GET requests is the same as for POST requests.
Below is the first solution I found. Thanks again for the responses. They were helpful in my experiments to learn how this worked!
Original Solution:
I finally fixed it, so I'll post my particular solution. However, I only went this route through lack of information how to execute this through an angular service. Ideally, a service would handle this kind of http request. Also note that when using $resource in services, it comes with a few functions one of which is save(). However, this also didn't work out for me.
Info on $http: https://docs.angularjs.org/api/ng/service/$http
Info on $resource: https://docs.angularjs.org/api/ngResource/service/$resource
Tutorial on Services and Factories (highly useful): http://viralpatel.net/blogs/angularjs-service-factory-tutorial/
articles.js controller
app.controller('FormCtrl', function($scope, $http) {
$scope.addPost = function() {
$scope.article = {
'article': {
'title' : $scope.article.title,
'body' : $scope.article.body
}
};
// Why can't I use Article.save() method from $resource?
$http({
method: 'POST',
url: 'http://localhost:3000/articles',
data: $scope.article
});
};
});
Since Rails is the backend, sending a POST request to the /articles path invokes the #create method. This was a simpler solution for me to understand than what I was trying before.
To understand using services: the $resource gives you access to the save() function. However, I still haven't demystified how to use it in this scenario. I went with $http because it's function was clear.
Sean Hill has a recommendation which is the second time I've seen today. It may be helpful to anyone else wrestling with this issue. If I come across a solution which uses services, I'll update this.
Thank you all for your help.
I've worked a lot with Angular and Rails, and I highly recommend using AngularJS Rails Resource. It makes working with a Rails backend just that much easier.
https://github.com/FineLinePrototyping/angularjs-rails-resource
You will need to specify this module in your app's dependencies and then you'll need to change your factory to look like this:
app.factory('Article', function(railsResourceFactory) {
return railsResourceFactory({url: '/articles', name: 'article');
});
Basically, based on the error that you are getting, what is happening is that your resource is not creating the correct article parameter. AngularJS Rails Resource does that for you, and it also takes care of other Rails-specific behavior.
Additionally, $scope.newPost should not be Article.save(). You should initialize it with a new resource new Article() instead.
Until your input fields are blank, no value is stored in model and you POST empty article object. You can fix it by creating client side validation or set default empty string value on needed fields before save.
First of all you should create new Article object in scope variable then pass newPost by params or access directly $scope.newPost in addArticle fn:
app.controller('ArticlesCtrl', function($scope, Article) {
$scope.articles = Article.query();
$scope.newPost = new Article();
$scope.addArticle = function(newPost) {
if (newPost.title == null) {
newPost.title = '';
}
// or if you have underscore or lodash:
// lodash.defaults(newPost, { title: '' });
Article.save(newPost);
};
});
If you want use CRUD operations you should setup resources like below:
$resource('/articles/:id.json', { id: '#id' }, {
update: {
method: 'PUT'
}
});
I have a controller that needs to redirect after receiving a file. I have saved the file successfully on the server side. Now, the only things that is bogging me down is how do I redirect to another site while sending the uploaded file that was saved on the server? Any tips? I am desparate.
OK so here it is, first I save the file on serverB:
file.SaveAs(Server.MapPath("~/ImageCache/") + file.FileName);
WebClient client = new WebClient();
Then I do the post:
byte[] data;
client.Headers.Set(HttpRequestHeader.ContentType, "image/jpeg");
data = client.UploadFile("http://hostA.com/Search/", "POST", Server.MapPath("~/ImageCache/") + file.FileName);
return Redirect( WHAT DO I WRITE HERE??);
Need to get to the place where I find the other service showing me the page when it has received the file.
How are you uploading the file? If this is the usual case of an <input type="file" />, you can just return Redirect("new url"); within your action.
Edit:
If you want to relay this to another web service, you don't need to redirect. There should be some sort of upload method defined in the webservice (including what type of webservice would help). You should be able to call that like you would any other webservice method, probably specifying the FileContents byte[] as a parameter.
I am integrating a 3rd party module into my site. I read their documention, but I stuck at this line:
"Your script should then do a server-to-server posting to our server. For example: https://www.domain.com:XXXX/gateway..."
What is it? I write a php page with a POST-form:
<form action"https://www.domain.com:XXXX/..." method="post">
...
<input type="submit">
Is it something like that?
Then do a response, let say they send back "result=ok", then I catch the result and do a check whether the result is okay or failed?
I interpret in this way, I dont know if I am doing the correct thing. CAn anyone advice? What is the server-to-server posting?
A server-to-server posting means that the program running on your server makes an HTTP POST to a gateway running on the vendor's server. The code fragment that you provided is HTML. You will need to have a code fragment in PHP (or some other language) to execute the POST. (If you did it in JavaScript, the post will come from your user's web browser, which is not what you want.)
You want to use the PHP HttpRequest class. Take a look at Example #2 in the PHP Manual, reprinted here:
<?php
$r = new HttpRequest('http://example.com/form.php', HttpRequest::METH_POST);
$r->setOptions(array('cookies' => array('lang' => 'de')));
$r->addPostFields(array('user' => 'mike', 'pass' => 's3c|r3t'));
$r->addPostFile('image', 'profile.jpg', 'image/jpeg');
try {
echo $r->send()->getBody();
} catch (HttpException $ex) {
echo $ex;
}
?>