I need to scrape private data from portal which doesn't support API.
IMPORTXML can't do this because of login.
I have a link with information of from & to date and the content is table with cost data. I need to login and scrape simple table into my Google Sheet.
I need to log in into this website:
https://www.glami.cz/registrace/prihlasit
and than scrape this url:
https://partner.glami.cz/s/e-commerce/days/866/?from=2016-12-01&to=2016-12-09
The form on this site is:
<form action="/registrace/prihlasit/" method="post" id="frm-signIn">
<dl class="form">
<dt><label for="frm-signIn-username" class="required">Emailová adresa</label></dt>
<dd><input type="text" name="username" id="frm-signIn-username" required data-nette-rules='[{"op":":filled","msg":"Prosím, vyplňte emailovou adresu."}]' class="text"></dd>
<dt><label for="frm-signIn-password" class="required">Heslo</label></dt>
<dd><input type="password" name="password" id="frm-signIn-password" required data-nette-rules='[{"op":":filled","msg":"Prosím, vyplňte heslo."}]' class="text"></dd>
<dt></dt>
<dd><input type="submit" name="send" value="Přihlásit se" class="button"></dd>
</dl>
<div><input type="hidden" name="_do" value="signIn-submit"></div>
</form>
I have this code which works for other websites. In this case the response from logger is still "didnt log in".
function fetchAdminPage() {
var url = "https://www.glami.cz/registrace/prihlasit";
var options = {
"method": "post",
"payload": {
'username': 'LOGIN',
'password': 'PASSWORD',
'send': 'Přihlásit se',
'_do': 'signIn-submit',
"testcookie": 1
},
"followRedirects": false
};
var response = UrlFetchApp.fetch(url, options);
if ( response.getResponseCode() == 200 ) {
// Incorrect user/pass combo
Logger.log("didnt log in");
} else if ( response.getResponseCode() == 302 ) {
// Logged-in
var headers = response.getAllHeaders();
if ( typeof headers['Set-Cookie'] !== 'undefined' ) {
// Make sure that we are working with an array of cookies
var cookies = typeof headers['Set-Cookie'] == 'string' ? [ headers['Set-Cookie'] ] : headers['Set-Cookie'];
for (var i = 0; i < cookies.length; i++) {
// We only need the cookie's value - it might have path, expiry time, etc here
cookies[i] = cookies[i].split( ';' )[0];
};
url = "https://partner.glami.cz/s/e-commerce/days/866/?from=2016-12-01&to=2016-12-09";
options = {
"method": "get",
// Set the cookies so that we appear logged-in
"headers": {
"Cookie": cookies.join(';')
}
};
response = UrlFetchApp.fetch(url, options);
};
Logger.log(response.getContentText());
};
}
The problem has to be I guess somewhere in payload/options or in url adress. Can't figure out what's wrong and how to log in succesfully.
Related
I am working on a WebApp Add-on in Google Sheets. Below is the Addon and webapp script. I want to read validation/error message from webapp and display to user.
Like I will send message from doPost(e) like "Check Values" and user should get this as message box.
function copyData() {
var ss_id = SpreadsheetApp.getActive().getId();
//This is the Web App URL.
var url = "https://script.google.com/macros/s/<id>/exec";
var payload = {
"ss_id" : ss_id, // Modified
}
var options = {
"method" : "POST",
"payload" : payload,
"followRedirects" : true,
"muteHttpExceptions" : true,
};
var result = UrlFetchApp.fetch(url, options);
}
function doPost(e) {
var ss_id = e.parameter.ss_id; // Modified
var response = {
"status" : "FAILED",
"ss_id" : ss_id,
};
//var ss_id = ss_id[0];
//Use your spreadsheetID to get Output Sheet
var Manager_SS=SpreadsheetApp.openById('<id>');
var Manager_Sheet=Manager_SS.getSheetByName('Consolidated_Data');
var FrontDesk_ss = SpreadsheetApp.openById(ss_id);
var FrontDesk_sheet = FrontDesk_ss.getSheetByName('Data');
//Get front desk data
var sData = FrontDesk_sheet.getRange("A2:C10").getValues();
//Copy data from Front Desk to Manager Sheet.
Manager_Sheet.getRange("A2:C10").clear();
Manager_Sheet.getRange("A2:C10").setValues(sData);
//Update done after copying data.
FrontDesk_sheet.getRange('D1:D10').setValue('Done');
var response = {
"status" : "SUCCESS",
"sData" : sData,
};
return ContentService.createTextOutput(JSON.stringify(response));
}
For this example I am using a bounded script, but this should be the same for an Editor Add-on
In the spreadsheet we want to validate, we create a custom menu to call a function that makes a POST request to our Web App. Depending on the response, we display one content or another.
const UI = SpreadsheetApp.getUi()
const onOpen = () => {
/* Adds the custom menu */
UI.createMenu('Custom Function').addItem('Is Valid?', 'checkValidity').addToUi()
}
const checkValidity = () => {
const res = UrlFetchApp.fetch
(
/* Change it for your URL */
"https://script.google.com/macros/s/<ID>/exec",
{
"method": "post",
"contentType": "application/json",
/* In this example I only send the ID of the Spreadsheet */
"payload": JSON.stringify(
{
"ss_id": SpreadsheetApp.getActiveSpreadsheet().getId()
}
)
}
)
/* Depending on the response from the Web App */
/* We show different messages */
const { MSG } = JSON.parse(res.getContentText())
UI.alert(MSG === "OK" ? "IS VALID" : "IS NOT VALID")
}
After we create a Web App that validates the ID. In this example I am only validating that the ID is contained in an array of valid IDs, but this should be replaced by whatever you need. As a response I only send a simple "OK" or "NOT OK", but this can be replaced with any kind of data.
const doPost = (e) => {
/* We perform the checks we need */
/* In this example only checking if the id is contained in an array */
/* This should be changed to perform the desired checks */
const validID = ["<VALID_ID_1>","<VALID_ID_2>"]
const { ss_id } = JSON.parse(e.postData.contents)
/* SpreadsheetApp.openById(ss_id).copy("my_new_copy") */
const checker = validID.includes(ss_id)
/* We send back the response */
/* Depending on the checker value */
return ContentService.createTextOutput(JSON.stringify(
{
"MSG": checker ? "OK" : "NOT OK"
}
)).setMimeType(ContentService.MimeType.JSON)
}
Reading Validation Error from Webapp
html:
<!DOCTYPE html>
<html>
<head>
<base target="_top">
</head>
<body>
<form>
<input type="text" id="txt1" name="id" placeholder="Enter Numbers only"/>
<input type="button" value="submit" onClick="processForm(this.parentNode);" />
</form>
<script>
function processForm(obj) {
console.log(obj.id.value);
if(obj.id.value.match(/[A-Za-z]/)) {
google.script.run.displayError("Invalid Characters Found in id field");
} else {
google.script.run.sendData(obj);
}
}
</script>
</body>
</html>
GS:
function doPost(e) {
Logger.log(e.postData.contents);
Logger.log(e.postData.type);
const ss = SpreadsheetApp.getActive();
const sh = ss.getSheetByName("Sheet1");
let data = JSON.parse(e.postData.contents);
let row = [];
Object.keys(data).forEach(k => row.push(data[k]));
Logger.log(JSON.stringify(row))
sh.appendRow(row);
}
function sendData(obj) {
const url = ScriptApp.getService().getUrl();
const params={"contentType":"application/json","payload":JSON.stringify(obj),"muteHttpExceptions":true,"method":"post","headers": {"Authorization": "Bearer " + ScriptApp.getOAuthToken()}};
UrlFetchApp.fetch(url,params);
}
function displayError(msg) {
SpreadsheetApp.getUi().alert(msg);
}
function launchMyDialog() {
SpreadsheetApp.getUi().showModelessDialog(HtmlService.createHtmlOutputFromFile('ah1'),'My Dialog');
}
Issue: An object created in JavaScript by input data from a signup form in HTML does not seem to be created.
Tried:
I checked if I was referencing the entire object with {data} rather just data
Searched other online resources to no avail
Read again on JavaScript objects to see if I did a simple mistake
adding debug strings to give me hints (I will list code below)
Relevant Code:
signup.html(each snippet is in top to bottom order):
<form id="signup-form" name ="signup-form">
<input class="login-form-field" type="text" name="user" placeholder="username">
<input class="login-form-field" type="text" name="email" placeholder="email">
<input class="login-form-field" type="password" name="dob" placeholder="date of birth">
<br>
<!--<button class="actionButton"></button>-->
<INPUT TYPE="button" NAME="button" Value="Click" onClick="signupData(this.form)">
</form>
//last of the markup body with Browserify compiled JavaScript files linked for functionality
<script src="browserify/builds/genKey.js"></script>
<script src="browserify/builds/SignUp.js"></script>
<script LANGUAGE="JavaScript">
function signupData(form) // add to this script
{
console.log("signup data is starting");
var user = form.user.value;
var email = form.email.value;
var dob = form.dob.value;
genSKey();
genPKey();
var skey = getSKey();
// var enUser = encryptMes(user);
// var enEmail = encryptMes(email);
var endob = encryptMes(dob);
var data = { name: "LifeNet", members: { user: {profilePic: {}, endob, listeners: {}, listening: {}, friends: {}, requested: {}, blocked:{}, channel: false} } }
apiPost({data});
// pass the signup function in here
// hash the variables and send to celox network
console.log(JSON.stringify({data}));
alert (`copy and save your Private Key to somewhere safe: ${skey}`);
}
</script>
signup.js (pre-Browserify build):
window.apiPost = function({data})
{
fetch("https://goldengates.club:3000/api/passData",
{
method: "post",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({data})
}
);
}
build.js (pre-Browserify build):
var eccrypto = require("eccrypto");
window.genSKey = function()
{
var secretKey = eccrypto.generatePrivate();
var SKey = JSON.stringify(secretKey);
localStorage.setItem("skey", SKey);
console.log(SKey);
alert(`your private key is ${SKey}`)
}
window.genPKey = function()
{
var skey = localStorage.getItem("skey");
var SKey = JSON.parse(skey);
let publicKey;
if(SKey != null)
{
publicKey = eccrypto.getPublic(SKey);
localStorage.setItem("pkey", JSON.stringify(publicKey));
return;
}
publicKey = eccrypto.getPublic(privateKey);
localStorage.setItem("pkey", JSON.stringify(publicKey));
return;
}
window.getPKey = function()
{
var PKey = localStorage.getItem("pkey");
var pkey = JSON.parse(PKey);
return pkey;
}
window.getSKey = function()
{
var SKey = localStorage.getItem("skey");
var skey = JSON.parse(SKey);
return skey;
}
window.encryptMes = function(data)
{
//for this you need to get the sender's public key to encrypt the message
if (localStorage.getItem("pkey") === null)
{
if (localStorage.getItem("skey") === null)
{
genSKey();
genPKey();
}
}
var pkey = getPKey();
encryptedMes = eccrypto.encrypt(pkey, Buffer.from(data));
return encryptedMes;
}
window.decryptMes = function(data)
{
if (localStorage.getItem("skey") === null)
{
genSKey();
}
var skey = getSKey();
decryptedMes = eccrypto.decrypt(SKey, data);
return decryptedMes.toString();
}
window.encryptData = function()
{
genSKey();
genPKey();
enMes = encryptedMes(/*add a document search for all fields on input form in login*/);
}
window.decryptData = function() {}
Error Code:
Browser:
It runs everything in the signup.html file besides console.log(JSON.stringify({data})); in the signupData(form) function.
Suspicious since the object that was created with user data should have been created and printed to the console.
My API Console:
I won't reference the API code since it seems to me that the object is just not being posted to it and that it isn't the problem.
TypeError: Cannot read property 'name' of undefined
at dataPool.setData (/home/main/public_html/Cypher-Network/src/app/data-Pool.js:64:27)
at /home/main/public_html/Cypher-Network/src/index.js:198:12
at Layer.handle [as handle_request] (/home/main/public_html/Cypher-Network/node_modules/express/lib/router/layer.js:95:5)
at next (/home/main/public_html/Cypher-Network/node_modules/express/lib/router/route.js:137:13)
at Route.dispatch (/home/main/public_html/Cypher-Network/node_modules/express/lib/router/route.js:112:3)
at Layer.handle [as handle_request] (/home/main/public_html/Cypher-Network/node_modules/express/lib/router/layer.js:95:5)
at /home/main/public_html/Cypher-Network/node_modules/express/lib/router/index.js:281:22
at Function.process_params (/home/main/public_html/Cypher-Network/node_modules/express/lib/router/index.js:335:12)
at next (/home/main/public_html/Cypher-Network/node_modules/express/lib/router/index.js:275:10)
at /home/main/public_html/Cypher-Network/src/index.js:62:3
Any form of help and explanation is greatly appreciated, as I am pretty new to the way JavaScript works.
Are you making use of NodeJs, and a framework like express? If yes, then you have to be sure that your backend is able to pass the incoming JSON request. If you use express, you can just use the express.json() middleware. Make sure you put it at the top of other middleware or just after the cors middleware like so
app.use(express.json())
That will parse the incoming data from the frontend.
Looking for direction or input on something I'm not familiar with. I created a two page site with a log in form that redirects user to the second page with the correct "access code" I created. It works as expected. What I would like to do is set a cookie when user is logged with jquery or vanilla js, then check if the user has logged in before and if they have not redirect back to log in form. I know I have not "tried anything" but just looking to learn and get an idea or advice
HTML:
<form class="form--log-in" id="log-in-form">
<div class="form-group">
<label for="firstName">First Name</label>
<input type="text" class="form-control" name="firstName" id="firstName" placeholder="First Name">
</div>
<div class="form-group">
<label for="lastName">Last Name</label>
<input type="text" class="form-control" name="lastName" id="lastName" placeholder="Last Name">
</div>
<div class="form-group">
<label for="userEmail">Email Address</label>
<input type="email" class="form-control" name="userEmail" id="userEmail" placeholder="Email Address">
</div>
<div class="form-group">
<label for="accessCode">Access Code</label>
<input type="text" class="form-control" name="accessCode" id="accessCode" placeholder="Access Code">
</div>
<div class="form--log-in__submit-container">
<button type="submit" class="btn button-submit form--log-in__submit" id="form_submit">
Log in
</button>
</div>
</form>
jquery:
// doc ready
$(function () {
checkCookie();
}
submitHandler: function (form) {
var formData = {
'method': 'register',
'firstName': $('input[name=firstName]').val(),
'lastName': $('input[name=lastName]').val(),
'userEmail': $('input[name=userEmail]').val(),
'accessCode': $('input[name=accessCode]').val(),
};
var validationObj = this;
$.ajax({
type: 'POST',
url: form_submit_endpoint,
data: formData,
success: function (res) {
var parsedResponse = JSON.parse(res);
if (parsedResponse.status === 'success') {
console.log('success');
_siteNS.Utils.setCookie('x-access',true,365);
logInModal();
} else if (parsedResponse.status === 'error') {
validationObj.showErrors({'accessCode': 'Incorrect Access Code.'});
console.log('error');
}
}
})
}
function _readCookie(name) {
var nameEQ = name + "=";
var ca = document.cookie.split(';');
for (var i = 0; i < ca.length; i++) {
var c = ca[i];
while (c.charAt(0) == ' ') {
c = c.substring(1, c.length);
}
if (c.indexOf(nameEQ) === 0) {
return c.substring(nameEQ.length, c.length);
}
}
return null;
}
function _setCookie(cookiename, value, numberofdays) {
var d = new Date();
d.setTime(d.getTime() + (numberofdays * 24 * 60 * 60 * 1000));
var expires = "expires=" + d.toUTCString();
document.cookie = cookiename + "=" + value + ";" + expires + ";path=/";
}
function checkCookie() {
// set cookie to boolean var
var myCookie = document.cookie === null;
//if the cookie is true and location is not the video page set location to video page
if(myCookie === true && (!location.href.match(/video-page/))){
window.location.replace('video-page');
}
//if the cookie is false and location is not the site root set location to site root
if(myCookie === false && (!location.href.match(/index/))){
window.location.replace('index');
}
}
Here is how you would do it.
After the ajax success, set a localstorage item like 'isLoggedIn', 'true'
In another JS file that is loaded for every page globally, you should check if localstorage flag is set to true.
Redirect to required page based on the result
NOTE: The above method is only to learn about how you can achieve auth. This is definitely not secure. You would have to use some kind of authentication like JWT and set the token in your localhost or cookie that will be sent to the server for each request.
Please do read about authentication before you build a real world app.
$.ajax({
type: 'POST',
url: form_endpoint,
data: formData,
success: function(res) {
var parsedResponse = JSON.parse(res);
if (parsedResponse.status === 'success') {
// set localstorage flag if successfully logged in
// NOTE: this is not secure. You need to have some kind of JWT token to be implemented
if (typeof(Storage) !== "undefined") {
localstorage.setItem('isLoggedIn', 'true');
} else {
// Sorry! No Web Storage support..
}
}
}
});
// In another JS file that is loaded globally
window.on('load', function() {
if (typeof(Storage) !== "undefined") {
const loginStatus = localstorage.getItem('isLoggedIn');
if (loginStatus === 'true') {
// redirect him to logged in page
} else {
// redirect him to unauthorized in page
}
} else {
// Sorry! No Web Storage support..
}
})
I have an extremely similar service like the one in this thread:
Php: Form auto-fill using $_SESSION variables with multiple php files
I would have asked there but since I don't have 50 reputation, I'll have to ask a new question.
To understand Ajax better I wanted to re-create rkmax's files and see if they would work. So I saved them as 5 separate files.
The SESSION does not seem to store any posted information. Added a print_r($_SESSION); to keep track of what's currently in there. Furthermore the .blur event to retrieve account information via the phone number doesn't work either.
Been banging my head against the wall for days with this one. It won't work when working either hosted locally via Apache/XAMPP or on an actual web server. All 5 files are in the same folder and titled exactly the same as rkmax's file titles.
I understand the logic behind each of the functions and can't seem to find a problem anywhere. I'm pretty new to coding so it could easily be something obvious like file structure or my own computer's settings?
Read a bunch of other StackOverflow threads with similar problems, but none of them seemed whatsoever applicable.
Thanks for your time.
Here's everything copied from rkmax's code:
index.php
<?php
session_start();
if (!isset($_SESSION['customers'])) {
$_SESSION['customers'] = array(
'1234567' => '{"lname": "Berg", "mi": "M", "fname": "Thomas", "account": "1234"}',
'1122334' => '{"lname": "Jordan", "mi": "C", "fname": "Jacky", "account": "4321"}',
);
}
require __DIR__ . '/index_template.php';
index_template.php
<!doctype html>
<html lang="es">
<head>
<meta charset="UTF-8">
<title>Document</title>
<script src="jquery.js"></script>
<script src="scripts.js"></script>
</head>
<body>
<div style="margin-left: 300px">
<form id="dataForm" method="post">
<fieldset>
<legend>User info</legend>
<label for="fname">First name</label>
<input id="fname" type="text" name="fname" placeholder="First name"/>
<label for="mi">Middle inicial</label>
<input id="mi" type="text" name="mi" placeholder="Middle Initial"/>
<label for="lname">Last name</label>
<input id="lname" type="text" name="lname" placeholder="Middle Initial"/>
<label for="phone">Phone number</label>
<input id="phone" type="text" name="phone" placeholder="000000"/>
</fieldset>
<fieldset>
<legend>Account info</legend>
<label for="account">Account</label>
<input id="account" type="text" name="account"/>
</fieldset>
<input type="submit" name="submit"/>
<input type="reset" name="clear"/>
</form>
</div>
</body>
</html>
postCustomerInformation.php
session_start();
// example: converts $_POST['phone'] into $post_phone if exists
extract($_POST, EXTR_PREFIX_ALL, 'post');
// Validates that all required information was sent
if (isset($post_lname) && isset($post_fname) && isset($post_phone) && isset($post_account)) {
$customer = array(
'fname' => $post_fname,
'lname' => $post_lname,
'account' => $post_account,
'mi' => isset($post_mi) ? $post_mi : '' // optional
);
$_SESSION['customers'][$post_phone] = json_encode($customer);
// returns a valid json format header
header('Content-Type: application/json');
header("HTTP/1.0 204 No Response");
} else {
// returns error
header('Content-Type: application/json');
header("HTTP/1.0 400 Bad Request");
}
getCustomerInformation.php
session_start();
// example: converts $_GET['phone'] into $get_phone if exists
extract($_GET, EXTR_PREFIX_ALL, 'get');
if (isset($get_phone) && isset($_SESSION['customers'][$get_phone])) {
header('Content-Type: application/json');
echo $_SESSION['customers'][$get_phone];
} else {
header('Content-Type: application/json');
echo '{}';
}
scripts.js
;(function () {
"use strict";
function getCustomerInformation() {
var phone = jQuery(this).val();
if (!phone) {
return;
}
jQuery.ajax({
type: 'get',
url: 'getCustomerInformation.php',
data: {
phone: phone
},
success: function getCustomerInformation_success(data) {
// for each returned value is assigned to the field
for (var i in data) {
if (data.hasOwnProperty(i)) {
$('#' + i).val(data[i]);
}
}
}
});
}
function postCustomerInformation(event) {
event.preventDefault();
var form = jQuery(this);
jQuery.ajax({
type: 'post',
url: 'postCustomerInformation.php',
data: form.serializeArray(),
success: function postCustomerInformation_success() {
alert("OK");
},
error: function postCustomerInformation_error() {
alert("Error");
}
})
}
// set behaviors when document is ready
jQuery(document).ready(function document_ready() {
jQuery('#phone').blur(getCustomerInformation);
jQuery('#dataForm').submit(postCustomerInformation);
});
})();
I would try and do something a bit scaled down, see if this is what you are trying to do. You only need 3 pages, the original form page, the php page, and the js file:
/ajax/dispatch.php
/*
** #param $phone [string] Gets key from session
*/
function getCustomerByPhone($phone)
{
if(!empty($_SESSION['customers'][$phone])) {
// I am decoding, but if you have the ability to set,
// create an array like below with success and data
$values = json_decode($_SESSION['customers'][$phone]);
die(json_encode(array("success"=>true,"data"=>$values)));
}
}
function makeError()
{
// Send back error
die(json_encode(array("success"=>false,"data"=>false)));
}
/*
** #param $array [string] This will be a query string generated from the
** jQuery serialize, so it's to be turned to array
*/
function updateSession($array)
{
// This should come back as a string, so you will need to parse it
$data = false;
parse_str(htmlspecialchars_decode($array),$data);
// Update the session
$_SESSION['customers'][$data['phone']] = json_encode($data);
die(json_encode(array("success"=>true,"data"=>$data)));
}
if(isset($_POST['phone'])) {
// If already exists, return to ajax the data
getCustomerByPhone($_POST['phone']);
}
elseif(isset($_POST['data'])) {
updateSession($_POST['data']);
}
// If not exists, return false
makeError();
/scripts.js
// I try not to duplicate things as much as possible
// so I would consider making an object to reuse
var AjaxEngine = function($)
{
this.ajax = function(url,data,func,method)
{
method = (typeof method === "undefined")? 'post' : 'get';
$.ajax({
url: url,
data: data,
type: method,
success: function(response) {
func(response);
}
});
};
};
$(document).ready(function(){
// Create instance
var Ajax = new AjaxEngine($);
var dispatcher = '/ajax/dispatch.php';
// On submit of form
$(this).on('submit','#dataForm',function(e) {
// Get the form
var thisForm = $(this);
// Stop form from firing
e.preventDefault();
// Run ajax to dispatch
Ajax.ajax(dispatcher,
// Serialize form
$('#dataForm').serialize(),
// Create an anonymous function to handle return
function(response) {
// Parse
var resp = JSON.parse(response);
// See if data exists
if(typeof resp.data === "undefined") {
console.log(resp.data);
return false;
}
// If there is a hit in session
else if(resp.success == true) {
// Loop through it and fill empty inputs in form
$.each(resp.data, function(k,v){
var input = $("input[name="+k+"]");
if(input.length > 0) {
if(input.val() == '') {
input.val(v);
}
}
});
}
// Run the session update
Ajax.ajax(dispatcher,
// This time send an action
// (just to differentiate from check function)
{
"action":"update",
"data":thisForm.serialize()
},
function(response) {
// Check your console.
console.log(response);
});
});
});
});
Started from scratch working on my answer pretty much nonstop, but gotta go to work soon, here's what I've got so far; I'm currently stuck on successfully sending the SESSION data back to the javascript and decoding it and displaying it successfully. Once I have that working I think sending those to the appropriate forms as well as the POST will be trivial. If anyone has any suggestions to speed me through this last part I would appreciate it.
Edit: Edited with the final solution.
index2.php
<?php
session_start();
if (!isset($_SESSION['customers'])) {
$_SESSION['customers'] = array(
'1111111' => '{"phone": "1111111", "fname": "Za", "lname": "Zo", "mi": "Z", "account": "1234"}',
'2222222' => '{"phone": "2222222", "fname": "La", "lname": "Li", "mi": "L", "account": "4321"}',
);
}
?>
<!DOCTYPE html>
<html lang="en">
<head>
<title> Assignment5 </title>
<meta charset = "utf-8" />
<script type = "text/javascript" src = "http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<script type = "text/javascript" src = "scripts.js"></script>
</head>
<body>
<form id="myform">
<input placeholder="Phone Number" name="phone" type="text" id="phone" maxlength="7" autofocus>
<input placeholder="First Name" name="fname" type="text" id="fname">
<input placeholder="Last Name" name="lname" type="text" id="lname">
<input placeholder="Middle Initial" name="mi" type="text" id="mi">
<input placeholder="Account Number" name="account" type="text" id="account" maxlength="4">
<input type="submit" value="Submit">
</form>
</body>
</html>
scripts.js
$(document).ready(function(){
$("#phone").blur(function(){
var session;
var currentPhone = $("#phone").val();
$.get("getPhone.php", {phone: currentPhone}, function(data) {
for (var i in data) {
if (data.hasOwnProperty(i)) {
$('#' + i).val(data[i]);
}
}
});
});
$("form").submit(function(){
var form = jQuery(this);
$.post("postPhone.php", form.serializeArray(), function(data) {
alert(data);
});
});
});
getPhone.php
<?php
session_start();
$nowPhone = $_GET["phone"];
if (array_key_exists($nowPhone, $_SESSION['customers'])) {
header('Content-Type: application/json');
echo $_SESSION['customers'][$nowPhone];
} else {
header('Content-Type: application/json');
echo '{}';
}
?>
postPhone.php
<?php
session_start();
if (isset($_POST["phone"]) && isset($_POST["fname"]) && isset($_POST["lname"]) && isset($_POST["mi"]) && isset($_POST["account"])) {
echo ("Submitted");
$customer = array(
'phone' => $_POST["phone"],
'fname' => $_POST["fname"],
'lname' => $_POST["lname"],
'mi' => $_POST["mi"],
'account' => $_POST["account"],
);
$_SESSION['customers'][$_POST["phone"]] = json_encode($customer);
}
else
echo ("All Information is Required");
?>
I am using HTML and using amazon EC2 (Linux free tier). I would like to use CloudFront, but my newsletter won't work. I am not an AWS expert, and I don't have a clue as to why it won't work on CloudFront.
My newsletter form looks like this:
<form id="subscribe" class="form" action="<?=$_SERVER['PHP_SELF']; ?>" method="post">
<div class="form-group form-inline">
<input size="15" type="text" class="form-control required" id="NewsletterName" name="NewsletterName" placeholder="Your name" />
<input size="25" type="email" class="form-control required" id="NewsletterEmail" name="NewsletterEmail" placeholder="your#email.com" />
<input type="submit" class="btn btn-default" value="SUBSCRIBE" />
<span id="response">
<? require_once('assets/mailchimp/inc/store-address.php'); if($_GET['submit']){ echo storeAddress(); } ?>
</span>
</div>
</form>
and my js file looks like this:
jQuery(document).ready(function() {
jQuery('#subscribe').submit(function() {
// update user interface
jQuery('#response').html('<span class="notice_message">Adding email address...</span>');
var name = jQuery('#NewsletterName').val().split(' ');
var fname = name[0];
var lname = name[1];
if ( fname == '' ) { fname=""; }
if ( lname == '' || lname === undefined) { lname=""; }
// Prepare query string and send AJAX request
jQuery.ajax({
url: 'assets/mailchimp/inc/store-address.php',
data: 'ajax=true&email=' + escape(jQuery('#NewsletterEmail').val()),
success: function(msg) {
if (msg.indexOf("Success") !=-1) {
jQuery('#response').html('<span class="success_message">Success! You are now
subscribed to our newsletter!</span>');
} else {
jQuery('#response').html('<span class="error_message">' + msg + '</span>');
}
}
});
return false;
});
});
and my php file looks like this:
<?php
function storeAddress(){
require_once('MCAPI.class.php'); // same directory as store-address.php
// grab an API Key from http://admin.mailchimp.com/account/api/
$api = new MCAPI('mymailchimpapi');
$merge_vars = Array(
'EMAIL' => $_GET['email'],
'FNAME' => $_GET['fname'],
'LNAME' => $_GET['lname']
);
// grab your List's Unique Id by going to http://admin.mailchimp.com/lists/
// Click the "settings" link for the list - the Unique Id is at the bottom of that page.
$list_id = "myuniqueid";
if($api->listSubscribe($list_id, $_GET['email'], $merge_vars , $_GET['emailtype']) === true) {
// It worked!
return 'Success! Check your inbox or spam folder for a message containing a
confirmation link.';
}else{
// An error ocurred, return error message
return '<b>Error:</b> ' . $api->errorMessage;
}
}
// If being called via ajax, autorun the function
if($_GET['ajax']){ echo storeAddress(); }
?>
The form works when I access it without using CloudFront, but I am worried of the server bandwidth that's why I want to use CloudFront. What happens is that when you click the submit button, the "adding email address" message will just appear for 1 second, and the email address entered is ignored.
Please make sure your CloudFront distribution is actually configured to handle POST/PUT requests. Take a look here for details: http://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/distribution-web-values-specify.html#DownloadDistValuesAllowedHTTPMethods